@@ -148,12 +148,23 @@ DEF_ISEL(SETBE_GPR8) = SETBE<R8W>;
148148
149149namespace {
150150
151+
152+ #define _BTClearUndefFlags () \
153+ do { \
154+ UndefFlag (of); \
155+ UndefFlag (sf); \
156+ UndefFlag (zf); \
157+ UndefFlag (af); \
158+ UndefFlag (pf); \
159+ } while (false )
160+
151161template <typename S1, typename S2>
152162DEF_SEM (BTreg, S1 src1, S2 src2) {
153163 auto val = Read (src1);
154164 auto bit = ZExtTo<S1>(Read (src2));
155165 auto bit_mask = UShl (Literal<S1>(1 ), URem (bit, BitSizeOf (src1)));
156166 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
167+ _BTClearUndefFlags ();
157168 return memory;
158169}
159170
@@ -164,6 +175,7 @@ DEF_SEM(BTmem, S1 src1, S2 src2) {
164175 auto index = UDiv (bit, BitSizeOf (src1));
165176 auto val = Read (GetElementPtr (src1, index));
166177 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
178+ _BTClearUndefFlags ();
167179 return memory;
168180}
169181
@@ -174,6 +186,7 @@ DEF_SEM(BTSreg, D dst, S1 src1, S2 src2) {
174186 auto bit_mask = UShl (Literal<S1>(1 ), URem (bit, BitSizeOf (val)));
175187 WriteZExt (dst, UOr (val, bit_mask));
176188 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
189+ _BTClearUndefFlags ();
177190 return memory;
178191}
179192
@@ -185,6 +198,7 @@ DEF_SEM(BTSmem, D dst, S1 src1, S2 src2) {
185198 auto val = Read (GetElementPtr (src1, index));
186199 Write (GetElementPtr (dst, index), UOr (val, bit_mask));
187200 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
201+ _BTClearUndefFlags ();
188202 return memory;
189203}
190204
@@ -195,6 +209,7 @@ DEF_SEM(BTRreg, D dst, S1 src1, S2 src2) {
195209 auto bit_mask = UShl (Literal<S1>(1 ), URem (bit, BitSizeOf (src1)));
196210 WriteZExt (dst, UAnd (val, UNot (bit_mask)));
197211 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
212+ _BTClearUndefFlags ();
198213 return memory;
199214}
200215
@@ -206,6 +221,7 @@ DEF_SEM(BTRmem, D dst, S1 src1, S2 src2) {
206221 auto val = Read (GetElementPtr (src1, index));
207222 Write (GetElementPtr (dst, index), UAnd (val, UNot (bit_mask)));
208223 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
224+ _BTClearUndefFlags ();
209225 return memory;
210226}
211227
@@ -216,6 +232,7 @@ DEF_SEM(BTCreg, D dst, S1 src1, S2 src2) {
216232 auto bit_mask = UShl (Literal<S1>(1 ), URem (bit, BitSizeOf (val)));
217233 WriteZExt (dst, UXor (val, bit_mask));
218234 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
235+ _BTClearUndefFlags ();
219236 return memory;
220237}
221238
@@ -227,9 +244,12 @@ DEF_SEM(BTCmem, D dst, S1 src1, S2 src2) {
227244 auto val = Read (GetElementPtr (src1, index));
228245 Write (GetElementPtr (dst, index), UXor (val, bit_mask));
229246 Write (FLAG_CF, UCmpNeq (UAnd (val, bit_mask), Literal<S1>(0 )));
247+ _BTClearUndefFlags ();
230248 return memory;
231249}
232250
251+ #undef _BTClearUndefFlags
252+
233253} // namespace
234254
235255DEF_ISEL_Mn_In (BT_MEMv_IMMb, BTmem);
@@ -323,11 +343,11 @@ DEF_SEM(BSR, D dst, S src) {
323343 auto index = USub (USub (BitSizeOf (src), count), Literal<S>(1 ));
324344 Write (FLAG_ZF, ZeroFlag (val));
325345 auto index_ret = Select (FLAG_ZF, Read (dst), ZExtTo<D>(index));
326- Write (FLAG_OF, false ); // Undefined, but experimentally 0.
327- Write (FLAG_SF, false ); // Undefined, but experimentally 0.
346+ Write (FLAG_OF, BUndefined () ); // Undefined, but experimentally 0.
347+ Write (FLAG_SF, BUndefined () ); // Undefined, but experimentally 0.
328348 Write (FLAG_PF, ParityFlag (index)); // Undefined, but experimentally 1.
329- Write (FLAG_AF, false ); // Undefined, but experimentally 0.
330- Write (FLAG_CF, false ); // Undefined, but experimentally 0.
349+ Write (FLAG_AF, BUndefined () ); // Undefined, but experimentally 0.
350+ Write (FLAG_CF, BUndefined () ); // Undefined, but experimentally 0.
331351 Write (dst, index_ret);
332352 return memory;
333353}
@@ -337,11 +357,11 @@ DEF_SEM(BSF, D dst, S src) {
337357 auto val = Read (src);
338358 Write (FLAG_ZF, ZeroFlag (val));
339359 auto index = Select (FLAG_ZF, Read (dst), ZExtTo<D>(CountTrailingZeros (val)));
340- Write (FLAG_OF, false ); // Undefined, but experimentally 0.
341- Write (FLAG_SF, false ); // Undefined, but experimentally 0.
360+ Write (FLAG_OF, BUndefined () ); // Undefined, but experimentally 0.
361+ Write (FLAG_SF, BUndefined () ); // Undefined, but experimentally 0.
342362 Write (FLAG_PF, ParityFlag (index));
343- Write (FLAG_AF, false ); // Undefined, but experimentally 0.
344- Write (FLAG_CF, false ); // Undefined, but experimentally 0.
363+ Write (FLAG_AF, BUndefined () ); // Undefined, but experimentally 0.
364+ Write (FLAG_CF, BUndefined () ); // Undefined, but experimentally 0.
345365 Write (dst, index);
346366 return memory;
347367}
0 commit comments