Fix mod/div/round argument side effects
This commit is contained in:
parent
c0490627bf
commit
befb415f27
|
|
@ -152,9 +152,11 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE; // PLIi
|
|||
// Base macros
|
||||
|
||||
// Return true if data[bit] set; not 0/1 return, but 0/non-zero return.
|
||||
// Arguments must not have side effects
|
||||
#define VL_BITISSETLIMIT_W(data, width, bit) (((bit) < (width)) && VL_BITISSET_W(data, bit))
|
||||
|
||||
// Shift appropriate word by bit. Does not account for wrapping between two words
|
||||
// Argument 'bit' must not have side effects
|
||||
#define VL_BITRSHIFT_W(data, bit) ((data)[VL_BITWORD_E(bit)] >> VL_BITBIT_E(bit))
|
||||
|
||||
// Create two 32-bit words from quadword
|
||||
|
|
@ -758,6 +760,7 @@ static inline IData VL_ONEHOT0_W(int words, WDataInP const lwp) VL_PURE {
|
|||
|
||||
static inline IData VL_CLOG2_I(IData lhs) VL_PURE {
|
||||
// There are faster algorithms, or fls GCC4 builtins, but rarely used
|
||||
// In C++20 there will be std::bit_width(lhs) - 1
|
||||
if (VL_UNLIKELY(!lhs)) return 0;
|
||||
--lhs;
|
||||
int shifts = 0;
|
||||
|
|
@ -953,11 +956,19 @@ static inline void VL_NEGATE_INPLACE_W(int words, WDataOutP owp_lwp) VL_MT_SAFE
|
|||
// EMIT_RULE: VL_MUL: oclean=dirty; lclean==clean; rclean==clean;
|
||||
// EMIT_RULE: VL_DIV: oclean=dirty; lclean==clean; rclean==clean;
|
||||
// EMIT_RULE: VL_MODDIV: oclean=dirty; lclean==clean; rclean==clean;
|
||||
#define VL_DIV_III(lbits, lhs, rhs) (((rhs) == 0) ? 0 : (lhs) / (rhs))
|
||||
#define VL_DIV_QQQ(lbits, lhs, rhs) (((rhs) == 0) ? 0 : (lhs) / (rhs))
|
||||
static inline IData VL_DIV_III(int lbits, IData lhs, IData rhs) {
|
||||
return (rhs == 0) ? 0 : lhs / rhs;
|
||||
}
|
||||
static inline QData VL_DIV_QQQ(int lbits, QData lhs, QData rhs) {
|
||||
return (rhs == 0) ? 0 : lhs / rhs;
|
||||
}
|
||||
#define VL_DIV_WWW(lbits, owp, lwp, rwp) (_vl_moddiv_w(lbits, owp, lwp, rwp, 0))
|
||||
#define VL_MODDIV_III(lbits, lhs, rhs) (((rhs) == 0) ? 0 : (lhs) % (rhs))
|
||||
#define VL_MODDIV_QQQ(lbits, lhs, rhs) (((rhs) == 0) ? 0 : (lhs) % (rhs))
|
||||
static inline IData VL_MODDIV_III(int lbits, IData lhs, IData rhs) {
|
||||
return (rhs == 0) ? 0 : lhs % rhs;
|
||||
}
|
||||
static inline QData VL_MODDIV_QQQ(int lbits, QData lhs, QData rhs) {
|
||||
return (rhs == 0) ? 0 : lhs % rhs;
|
||||
}
|
||||
#define VL_MODDIV_WWW(lbits, owp, lwp, rwp) (_vl_moddiv_w(lbits, owp, lwp, rwp, 1))
|
||||
|
||||
static inline WDataOutP VL_ADD_W(int words, WDataOutP owp, WDataInP const lwp,
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ extern "C" void __gcov_dump();
|
|||
// Now that C++ requires these standard types the vl types are deprecated
|
||||
#include <cstdint>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef VL_NO_LEGACY
|
||||
using vluint8_t = uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||
|
|
@ -445,11 +446,14 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
|
|||
#define VL_SIZEBITS_E (VL_EDATASIZE - 1) ///< Bit mask for bits in a quad
|
||||
|
||||
/// Return mask for words with 1's where relevant bits are (0=all bits)
|
||||
/// Arguments must not have side effects
|
||||
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) ? ((1U << ((nbits) & VL_SIZEBITS_I)) - 1) : ~0)
|
||||
/// Return mask for quads with 1's where relevant bits are (0=all bits)
|
||||
/// Arguments must not have side effects
|
||||
#define VL_MASK_Q(nbits) \
|
||||
(((nbits) & VL_SIZEBITS_Q) ? ((1ULL << ((nbits) & VL_SIZEBITS_Q)) - 1ULL) : ~0ULL)
|
||||
/// Return mask for EData with 1's where relevant bits are (0=all bits)
|
||||
/// Arguments must not have side effects
|
||||
#define VL_MASK_E(nbits) VL_MASK_I(nbits)
|
||||
|
||||
#define VL_EUL(n) VL_UL(n) // Make constant number EData sized
|
||||
|
|
@ -471,8 +475,12 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
|
|||
// #defines, to avoid requiring math.h on all compile runs
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define VL_TRUNC(n) (((n) < 0) ? std::ceil((n)) : std::floor((n)))
|
||||
# define VL_ROUND(n) (((n) < 0) ? std::ceil((n)-0.5) : std::floor((n) + 0.5))
|
||||
static inline double VL_TRUNC(double n) {
|
||||
return (n < 0) ? std::ceil(n) : std::floor(n);
|
||||
}
|
||||
static inline double VL_ROUND(double n) {
|
||||
return (n < 0) ? std::ceil(n-0.5) : std::floor(n + 0.5);
|
||||
}
|
||||
#else
|
||||
# define VL_TRUNC(n) std::trunc(n)
|
||||
# define VL_ROUND(n) std::round(n)
|
||||
|
|
|
|||
Loading…
Reference in New Issue