Skip to content

Commit 93aba7c

Browse files
authored
Added binop forms of sign and zero flags (#567)
* added binop forms of sign and zero flags * added passing real rhs for aarch64
1 parent 327ecc1 commit 93aba7c

File tree

12 files changed

+116
-93
lines changed

12 files changed

+116
-93
lines changed

lib/Arch/AArch64/Semantics/BINARY.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ DEF_ISEL(SUB_64_ADDSUB_EXT) = SUB<R64W, R64, I64>;
4646
namespace {
4747

4848
template <typename T>
49-
T AddWithCarryNZCV(State &state, T lhs, T rhs, T carry) {
49+
T AddWithCarryNZCV(State &state, T lhs, T rhs, T actual_rhs, T carry) {
5050
auto unsigned_result = UAdd(UAdd(ZExt(lhs), ZExt(rhs)), ZExt(carry));
5151
auto signed_result = SAdd(SAdd(SExt(lhs), SExt(rhs)), Signed(ZExt(carry)));
5252
auto result = TruncTo<T>(unsigned_result);
53-
FLAG_N = SignFlag(result);
54-
FLAG_Z = ZeroFlag(result);
53+
FLAG_N = SignFlag(result, lhs, actual_rhs);
54+
FLAG_Z = ZeroFlag(result, lhs, actual_rhs);
5555
FLAG_C = UCmpNeq(ZExt(result), unsigned_result);
56-
FLAG_V = SCmpNeq(SExt(result), signed_result);
56+
FLAG_V = __remill_flag_computation_overflow(
57+
SCmpNeq(SExt(result), signed_result), lhs, actual_rhs, result);
5758
return result;
5859
}
5960

@@ -62,7 +63,7 @@ DEF_SEM(SUBS, D dst, S1 src1, S2 src2) {
6263
using T = typename BaseType<S2>::BT;
6364
auto lhs = Read(src1);
6465
auto rhs = Read(src2);
65-
auto res = AddWithCarryNZCV(state, lhs, UNot(rhs), T(1));
66+
auto res = AddWithCarryNZCV(state, lhs, UNot(rhs), rhs, T(1));
6667
WriteZExt(dst, res);
6768
return memory;
6869
}
@@ -72,7 +73,7 @@ DEF_SEM(ADDS, D dst, S1 src1, S2 src2) {
7273
using T = typename BaseType<S2>::BT;
7374
auto lhs = Read(src1);
7475
auto rhs = Read(src2);
75-
auto res = AddWithCarryNZCV(state, lhs, rhs, T(0));
76+
auto res = AddWithCarryNZCV(state, lhs, rhs, rhs, T(0));
7677
WriteZExt(dst, res);
7778
return memory;
7879
}
@@ -193,7 +194,8 @@ DEF_SEM(SBC, D dst, S src1, S src2) {
193194
template <typename D, typename S>
194195
DEF_SEM(SBCS, D dst, S src1, S src2) {
195196
auto carry = ZExtTo<S>(Unsigned(FLAG_C));
196-
auto res = AddWithCarryNZCV(state, Read(src1), UNot(Read(src2)), carry);
197+
auto res =
198+
AddWithCarryNZCV(state, Read(src1), UNot(Read(src2)), Read(src2), carry);
197199
WriteZExt(dst, res);
198200
return memory;
199201
}
@@ -347,7 +349,7 @@ void FCompare(State &state, S val1, S val2, bool signal = true) {
347349
state.sr.ioc = true;
348350
}
349351

350-
// Regular float compare
352+
// Regular float compare
351353
} else {
352354
if (FCmpEq(val1, val2)) {
353355

lib/Arch/AArch64/Semantics/COND.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ template <bool (*check_cond)(const State &), typename S1, typename S2>
9393
DEF_SEM(CCMP, S1 src1, S2 src2, S2 nzcv) {
9494
using T = typename BaseType<S1>::BT;
9595
if (check_cond(state)) {
96-
(void) AddWithCarryNZCV(state, Read(src1), UNot(Read(src2)), T(1));
96+
(void) AddWithCarryNZCV(state, Read(src1), UNot(Read(src2)), Read(src2),
97+
T(1));
9798
} else {
9899
auto nzcv_val = Read(nzcv);
99100
FLAG_V = UCmpNeq(UAnd(nzcv_val, T(1)), T(0));
@@ -108,7 +109,7 @@ template <bool (*check_cond)(const State &), typename S1, typename S2>
108109
DEF_SEM(CCMN, S1 src1, S2 src2, S2 nzcv) {
109110
using T = typename BaseType<S1>::BT;
110111
if (check_cond(state)) {
111-
(void) AddWithCarryNZCV(state, Read(src1), Read(src2), T(0));
112+
(void) AddWithCarryNZCV(state, Read(src1), Read(src2), Read(src2), T(0));
112113
} else {
113114
auto nzcv_val = Read(nzcv);
114115
FLAG_V = UCmpNeq(UAnd(nzcv_val, T(1)), T(0));

lib/Arch/AArch64/Semantics/FLAGS.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,29 @@ namespace {
2020
// is executed.
2121
enum : uint32_t { kLHS = 2415899639U, kRHS = 70623199U };
2222

23+
// Zero flags, tells us whether or not a value is zero.
24+
template <typename T, typename S1, typename S2>
25+
[[gnu::const]] ALWAYS_INLINE static bool ZeroFlag(T res, S1 lhs, S2 rhs) {
26+
return __remill_flag_computation_zero(T(0) == res, lhs, rhs, res);
27+
}
28+
2329
// Zero flags, tells us whether or not a value is zero.
2430
template <typename T>
2531
[[gnu::const]] ALWAYS_INLINE static bool ZeroFlag(T res) {
26-
return __remill_flag_computation_zero(T(0) == res, res);
32+
return T(0) == res;
2733
}
2834

35+
2936
// Zero flags, tells us whether or not a value is zero.
30-
template <typename T>
31-
[[gnu::const]] ALWAYS_INLINE static bool NotZeroFlag(T res) {
32-
return !__remill_flag_computation_zero(T(0) == res, res);
37+
template <typename T, typename S1, typename S2>
38+
[[gnu::const]] ALWAYS_INLINE static bool NotZeroFlag(T res, S1 lhs, S2 rhs) {
39+
return !__remill_flag_computation_zero(T(0) == res, lhs, rhs, res);
3340
}
3441

3542
// Sign flag, tells us if a result is signed or unsigned.
36-
template <typename T>
37-
[[gnu::const]] ALWAYS_INLINE static bool SignFlag(T res) {
38-
return __remill_flag_computation_sign(0 > Signed(res), res);
43+
template <typename T, typename S1, typename S2>
44+
[[gnu::const]] ALWAYS_INLINE static bool SignFlag(T res, S1 lhs, S2 rhs) {
45+
return __remill_flag_computation_sign(0 > Signed(res), lhs, rhs, res);
3946
}
4047

4148
// Tests whether there is an even number of bits in the low order byte.
@@ -74,7 +81,8 @@ struct Overflow<tag_add> {
7481
const T sign_lhs = lhs >> kSignShift;
7582
const T sign_rhs = rhs >> kSignShift;
7683
const T sign_res = res >> kSignShift;
77-
return 2 == (sign_lhs ^ sign_res) + (sign_rhs ^ sign_res);
84+
return __remill_flag_computation_overflow(
85+
2 == (sign_lhs ^ sign_res) + (sign_rhs ^ sign_res), lhs, rhs, res);
7886
}
7987
};
8088

lib/Arch/AArch64/Semantics/LOGICAL.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ template <typename D, typename S1, typename S2>
5656
DEF_SEM(BICS, D dst, S1 src1, S2 src2) {
5757
auto res = UAnd(Read(src1), UNot(Read(src2)));
5858
WriteZExt(dst, res);
59-
FLAG_N = SignFlag(res);
60-
FLAG_Z = ZeroFlag(res);
59+
FLAG_N = SignFlag(res, src1, src2);
60+
FLAG_Z = ZeroFlag(res, src1, src2);
6161
FLAG_C = false;
6262
FLAG_V = false;
6363
return memory;
@@ -99,8 +99,8 @@ template <typename D, typename S1, typename S2>
9999
DEF_SEM(ANDS, D dst, S1 src1, S2 src2) {
100100
auto res = UAnd(Read(src1), Read(src2));
101101
WriteZExt(dst, res);
102-
FLAG_N = SignFlag(res);
103-
FLAG_Z = ZeroFlag(res);
102+
FLAG_N = SignFlag(res, src1, src2);
103+
FLAG_Z = ZeroFlag(res, src1, src2);
104104
FLAG_C = false;
105105
FLAG_V = false;
106106
return memory;

lib/Arch/SPARC32/Semantics/BINARY.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ namespace {
66

77
template <typename Tag, typename T>
88
ALWAYS_INLINE static void WriteFlagsIncDec(State &state, T lhs, T rhs, T res) {
9-
FLAG_ICC_ZF = ZeroFlag(res);
10-
FLAG_ICC_NF = SignFlag(res);
9+
FLAG_ICC_ZF = ZeroFlag(res, lhs, rhs);
10+
FLAG_ICC_NF = SignFlag(res, lhs, rhs);
1111
FLAG_ICC_VF = Overflow<Tag>::Flag(lhs, rhs, res);
1212
}
1313

@@ -20,16 +20,16 @@ ALWAYS_INLINE static void WriteFlagsAddSub(State &state, T lhs, T rhs, T res) {
2020
template <typename Tag, typename T>
2121
ALWAYS_INLINE static void WriteXCCFlagsIncDec(State &state, T lhs, T rhs,
2222
T res) {
23-
FLAG_XCC_ZF = ZeroFlag(res);
24-
FLAG_XCC_NF = SignFlag(res);
23+
FLAG_XCC_ZF = ZeroFlag(res, lhs, rhs);
24+
FLAG_XCC_NF = SignFlag(res, lhs, rhs);
2525
FLAG_XCC_VF = Overflow<Tag>::Flag(lhs, rhs, res);
2626
}
2727

2828
template <typename Tag, typename T>
2929
ALWAYS_INLINE static void WriteICCFlagsIncDec(State &state, T lhs, T rhs,
3030
T res) {
31-
FLAG_ICC_ZF = ZeroFlag(res);
32-
FLAG_ICC_NF = SignFlag(res);
31+
FLAG_ICC_ZF = ZeroFlag(res, lhs, rhs);
32+
FLAG_ICC_NF = SignFlag(res, lhs, rhs);
3333
FLAG_ICC_VF = Overflow<Tag>::Flag(lhs, rhs, res);
3434
}
3535

@@ -145,8 +145,8 @@ DEF_SEM(SMULcc, S1 src1, S2 src2, D dst) {
145145
auto rhs_wide = SExt(rhs);
146146
auto res = SMul(lhs_wide, rhs_wide);
147147
auto res_trunc = TruncTo<S1>(res);
148-
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(res));
149-
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(res));
148+
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(res), src1, src2);
149+
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(res), src1, src2);
150150
FLAG_ICC_VF = 0;
151151
FLAG_ICC_CF = 0;
152152
auto index = Literal<S1>(32);
@@ -176,8 +176,8 @@ DEF_SEM(UMULcc, S1 src1, S2 src2, D dst) {
176176
auto rhs_wide = ZExt(rhs);
177177
auto res = UMul(lhs_wide, rhs_wide);
178178
auto res_trunc = TruncTo<S1>(res);
179-
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(res));
180-
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(res));
179+
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(res), src1, src2);
180+
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(res), src1, src2);
181181
FLAG_ICC_VF = 0;
182182
FLAG_ICC_CF = 0;
183183
auto index = Literal<S1>(32);
@@ -223,8 +223,8 @@ DEF_SEM(SDIVcc, S1 src1, S2 src2, D dst) {
223223
auto rhs = Read(src2);
224224
auto rhs_wide = SExt(rhs);
225225
auto quot = SDiv(y_lhs_wide, rhs_wide);
226-
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(quot));
227-
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(quot));
226+
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(quot), src1, src2);
227+
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(quot), src1, src2);
228228
FLAG_ICC_VF = Overflow<tag_sdiv>::Flag(lhs, rhs, quot);
229229
FLAG_ICC_CF = 0;
230230
auto res = Overflow<tag_sdiv>::Value(lhs, rhs, quot);
@@ -250,8 +250,8 @@ DEF_SEM(UDIVcc, S1 src1, S2 src2, D dst) {
250250
auto lhs_wide = ZExt(lhs);
251251
auto rhs_wide = ZExt(rhs);
252252
auto quot = UDiv(lhs_wide, rhs_wide);
253-
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(quot));
254-
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(quot));
253+
FLAG_ICC_NF = SignFlag(static_cast<uint32_t>(quot), src1, src2);
254+
FLAG_ICC_ZF = ZeroFlag(static_cast<uint32_t>(quot), src1, src2);
255255
FLAG_ICC_VF = Overflow<tag_udiv>::Flag(lhs, rhs, quot);
256256
FLAG_ICC_CF = 0;
257257
auto res = Overflow<tag_udiv>::Value(lhs, rhs, quot);

lib/Arch/SPARC32/Semantics/FLAGS.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,21 @@
1919
namespace {
2020

2121
// Zero flags, tells us whether or not a value is zero.
22-
template <typename T>
23-
[[gnu::const]] ALWAYS_INLINE static bool ZeroFlag(T res) {
24-
return __remill_flag_computation_zero(T(0) == res, res);
22+
template <typename T, typename S1, typename S2>
23+
[[gnu::const]] ALWAYS_INLINE static bool ZeroFlag(T res, S1 lhs, S2 rhs) {
24+
return __remill_flag_computation_zero(T(0) == res, lhs, rhs, res);
2525
}
2626

2727
// Zero flags, tells us whether or not a value is zero.
28-
template <typename T>
29-
[[gnu::const]] ALWAYS_INLINE static bool NotZeroFlag(T res) {
30-
return !__remill_flag_computation_zero(T(0) == res);
28+
template <typename T, typename S1, typename S2>
29+
[[gnu::const]] ALWAYS_INLINE static bool NotZeroFlag(T res, S1 lhs, S2 rhs) {
30+
return !__remill_flag_computation_zero(T(0) == res, lhs, rhs, res);
3131
}
3232

3333
// Sign flag, tells us if a result is signed or unsigned.
34-
template <typename T>
35-
[[gnu::const]] ALWAYS_INLINE static bool SignFlag(T res) {
36-
return __remill_flag_computation_sign(0 > Signed(res), res);
34+
template <typename T, typename S1, typename S2>
35+
[[gnu::const]] ALWAYS_INLINE static bool SignFlag(T res, S1 lhs, S2 rhs) {
36+
return __remill_flag_computation_sign(0 > Signed(res), lhs, rhs, res);
3737
}
3838

3939
// Tests whether there is an even number of bits in the low order byte.

lib/Arch/SPARC32/Semantics/LOGICAL.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ namespace {
77
template <typename T>
88
ALWAYS_INLINE void SetFlagsLogical(State &state, T lhs, T rhs, T res) {
99
FLAG_ICC_CF = false;
10-
FLAG_ICC_ZF = ZeroFlag(res);
11-
FLAG_ICC_NF = SignFlag(res);
10+
FLAG_ICC_ZF = ZeroFlag(res, lhs, rhs);
11+
FLAG_ICC_NF = SignFlag(res, lhs, rhs);
1212
FLAG_ICC_VF = false;
1313
}
1414

0 commit comments

Comments
 (0)