@@ -25,19 +25,19 @@ enum : uint32_t { kLHS = 2415899639U, kRHS = 70623199U };
2525// Zero flags, tells us whether or not a value is zero.
2626template <typename T>
2727[[gnu::const ]] ALWAYS_INLINE static bool ZeroFlag (T res) {
28- return T (0 ) == res;
28+ return __remill_flag_computation_zero ( T (0 ) == res, res) ;
2929}
3030
3131// Zero flags, tells us whether or not a value is zero.
3232template <typename T>
3333[[gnu::const ]] ALWAYS_INLINE static bool NotZeroFlag (T res) {
34- return T (0 ) != res;
34+ return ! __remill_flag_computation_zero ( T (0 ) == res, res) ;
3535}
3636
3737// Sign flag, tells us if a result is signed or unsigned.
3838template <typename T>
3939[[gnu::const ]] ALWAYS_INLINE static bool SignFlag (T res) {
40- return 0 > Signed (res);
40+ return __remill_flag_computation_sign ( 0 > Signed (res), res);
4141}
4242
4343// Auxiliary carry flag. This is used for binary coded decimal operations and
@@ -97,7 +97,8 @@ struct Overflow<tag_add> {
9797 const T sign_lhs = lhs >> kSignShift ;
9898 const T sign_rhs = rhs >> kSignShift ;
9999 const T sign_res = res >> kSignShift ;
100- return 2 == ((sign_lhs ^ sign_res) + (sign_rhs ^ sign_res));
100+ return __remill_flag_computation_overflow (
101+ 2 == ((sign_lhs ^ sign_res) + (sign_rhs ^ sign_res)), lhs, rhs, res);
101102 }
102103};
103104
@@ -114,7 +115,8 @@ struct Overflow<tag_sub> {
114115 const T sign_lhs = lhs >> kSignShift ;
115116 const T sign_rhs = rhs >> kSignShift ;
116117 const T sign_res = res >> kSignShift ;
117- return 2 == ((sign_lhs ^ sign_rhs) + (sign_lhs ^ sign_res));
118+ return __remill_flag_computation_overflow (
119+ 2 == ((sign_lhs ^ sign_rhs) + (sign_lhs ^ sign_res)), lhs, rhs, res);
118120 }
119121};
120122
@@ -126,10 +128,11 @@ struct Overflow<tag_mul> {
126128 // the operands.
127129 template <typename T, typename R>
128130 [[gnu::const ]] ALWAYS_INLINE static bool
129- Flag (T, T, R res,
131+ Flag (T lhs , T rhs , R res,
130132 typename std::enable_if<sizeof (T) < sizeof (R), int >::type = 0 ) {
131133
132- return static_cast <R>(static_cast <T>(res)) != res;
134+ return __remill_flag_computation_overflow (
135+ static_cast <R>(static_cast <T>(res)) != res, lhs, rhs, res);
133136 }
134137
135138 // Signed integer multiplication overflow check, where the result is
@@ -155,24 +158,28 @@ struct Carry<tag_add> {
155158 [[gnu::const ]] ALWAYS_INLINE static bool Flag (T lhs, T rhs, T res) {
156159 static_assert (std::is_unsigned<T>::value,
157160 " Invalid specialization of `Carry::Flag` for addition." );
158- return res < lhs || res < rhs;
161+ return __remill_flag_computation_carry (res < lhs || res < rhs, lhs, rhs,
162+ res);
159163 }
160164};
161165
162166// Computes an carry flag when one number is subtracted from another.
163167template <>
164168struct Carry <tag_sub> {
165169 template <typename T>
166- [[gnu::const ]] ALWAYS_INLINE static bool Flag (T lhs, T rhs, T) {
170+ [[gnu::const ]] ALWAYS_INLINE static bool Flag (T lhs, T rhs, T res ) {
167171 static_assert (std::is_unsigned<T>::value,
168172 " Invalid specialization of `Carry::Flag` for addition." );
169- return lhs < rhs;
173+ return __remill_flag_computation_carry ( lhs < rhs, lhs, rhs, res) ;
170174 }
171175};
172176
173177} // namespace
174178
175- #define UndefFlag (name ) do { state.aflag .name = __remill_undefined_8 (); } while (false )
179+ #define UndefFlag (name ) \
180+ do { \
181+ state.aflag .name = __remill_undefined_8 (); \
182+ } while (false )
176183
177184#define ClearArithFlags () \
178185 do { \
0 commit comments