Skip to content

Commit bfe0399

Browse files
committed
refactor(store.cpp): align store event generate with NEMU
Rewrite StoreRecorder::check case vecNeedSplit. Read Comments for detailed logic. BREAKING CHANGE: store event generate is not backward compatible!
1 parent c2d24d5 commit bfe0399

File tree

1 file changed

+55
-70
lines changed

1 file changed

+55
-70
lines changed

src/test/csrc/difftest/checkers/store.cpp

Lines changed: 55 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@
2020
#include <sys/types.h>
2121

2222
#ifdef CONFIG_DIFFTEST_STOREEVENT
23+
24+
// Expand an 8-bit mask to a 64-bit wide data mask, like from 0x99 to 0xF00FF00F
25+
static uint64_t MaskExpand(uint8_t mask) {
26+
uint64_t expander = 0x0101010101010101ULL;
27+
uint64_t selector = 0x8040201008040201ULL;
28+
return (((((mask * expander) & selector) * 0xFFULL) >> 7) & expander) * 0xFFULL;
29+
}
30+
31+
// safe bitmask function to avoid overflow or underflow
32+
#define SAFE_BITMASK(bits) (((bits) >= 64ULL) ? (~0ULL) : ((1ULL << (bits)) - 1ULL))
33+
#define SAFE_BITMASKRANGE(hi, lo) (SAFE_BITMASK(hi) & (~SAFE_BITMASK(lo)))
34+
#define MAX_OF(a, b) ((a) > (b) ? (a) : (b))
35+
#define MIN_OF(a, b) ((a) < (b) ? (a) : (b))
36+
2337
bool StoreRecorder::get_valid(const DifftestStoreEvent &probe) {
2438
return probe.valid;
2539
}
@@ -44,84 +58,55 @@ int StoreRecorder::check(const DifftestStoreEvent &probe) {
4458
auto pc = probe.pc;
4559
auto robIdx = probe.robidx;
4660

47-
uint64_t rawVecAddr = addr + offset;
48-
4961
if (probe.vecNeedSplit) {
62+
// handling by elements firstly
63+
// then check each element whether it crosses a 8B boundary
5064
uint16_t flow = COMMITBYTES / eew;
51-
uint64_t flowMask = (eew == 1) ? 0x1ULL : (eew == 2) ? 0x3ULL : (eew == 4) ? 0xfULL : (eew == 8) ? 0xffULL : 0x0ULL;
52-
uint64_t flowMaskBit = (eew == 1) ? 0xffULL
53-
: (eew == 2) ? 0xffffULL
54-
: (eew == 4) ? 0xffffffffULL
55-
: (eew == 8) ? 0xffffffffffffffffULL
56-
: 0x0ULL;
57-
58-
// cross 128bits.
59-
bool handleMisalign = ((mask << (16 - offset)) & 0xFFFF) != 0;
60-
// For requests exceeding 128 bits, we perform fragmentation.
61-
// Processing the high-order bits of data exceeding 128 bits.
62-
if (handleMisalign) {
63-
uint64_t selVecData = offset >= 8 ? highData : lowData;
64-
uint16_t rawOffset = offset % 8;
65-
uint64_t refStoreCommitData = selVecData << (64 - (rawOffset * 8)) >> (64 - (rawOffset * 8));
66-
uint8_t refStoreCommitMask = mask << rawOffset >> rawOffset;
67-
DiffState::StoreCommit storeCommit = {probe.valid,
68-
addr,
69-
refStoreCommitData,
70-
refStoreCommitMask,
71-
pc,
72-
robIdx
65+
uint16_t eew_off = offset % eew;
66+
67+
for (int i = -1; i < flow; i++) {
68+
uint64_t flowMask =
69+
mask & SAFE_BITMASKRANGE(MAX_OF(i * eew + eew_off + eew, 64LL), MIN_OF(i * eew + eew_off, 0LL));
70+
uint8_t commitLowMask = flowMask & 0XFF;
71+
bool commitLowValid = probe.valid && commitLowMask;
72+
uint64_t commitLowAddr = addr;
73+
uint64_t commitLowData = lowData & MaskExpand(commitLowMask);
74+
75+
if (commitLowValid) {
76+
77+
DiffState::StoreCommit storeCommitLow = {commitLowValid,
78+
commitLowAddr,
79+
commitLowData,
80+
commitLowMask,
81+
pc,
82+
robIdx
7383
#ifdef CONFIG_DIFFTEST_SQUASH
74-
,
75-
probe.stamp
84+
,
85+
probe.stamp
7686
#endif // CONFIG_DIFFTEST_SQUASH
77-
};
78-
79-
state->store_event_queue.push(storeCommit);
80-
}
81-
for (int i = 0; i < flow; i++) {
82-
uint32_t rawOffset = eew * i + offset;
83-
uint32_t nextOffset = rawOffset + eew;
84-
85-
// to next sbuffer write event.
86-
if (rawOffset >= 16)
87-
break;
88-
89-
uint64_t selVecData = rawOffset >= 8 ? highData : lowData;
90-
auto dataOffset = (rawOffset * 8) % 64;
91-
auto refStoreCommitAddr = rawVecAddr + eew * i;
92-
uint8_t refStoreCommitMask = (mask >> rawOffset) & flowMask;
93-
94-
if (refStoreCommitMask == 0)
95-
continue;
96-
97-
uint64_t refStoreCommitData;
98-
bool needNextData = (rawOffset < 8) && (nextOffset > 8);
99-
100-
if (needNextData) {
101-
auto presentDataOffset = dataOffset;
102-
auto presentData = lowData >> presentDataOffset;
103-
104-
nextOffset = 8 - rawOffset;
105-
auto nextDataOffset = nextOffset * 8;
106-
auto nextData = probe.highData << nextDataOffset;
107-
108-
refStoreCommitData = (nextData + presentData) & flowMaskBit;
109-
} else {
110-
refStoreCommitData = (selVecData >> dataOffset) & flowMaskBit;
87+
};
88+
state->store_event_queue.push(storeCommitLow);
11189
}
11290

113-
DiffState::StoreCommit storeCommit = {probe.valid,
114-
refStoreCommitAddr,
115-
refStoreCommitData,
116-
refStoreCommitMask,
117-
pc,
118-
robIdx
91+
uint8_t commitHighMask = (flowMask >> 8) & 0xFF;
92+
bool commitHighValid = probe.valid && commitHighMask;
93+
uint64_t commitHighAddr = addr + 8;
94+
uint64_t commitHighData = highData & MaskExpand(commitHighMask);
95+
96+
if (commitHighValid) {
97+
DiffState::StoreCommit storeCommitHigh = {commitHighValid,
98+
commitHighAddr,
99+
commitHighData,
100+
commitHighMask,
101+
pc,
102+
robIdx
119103
#ifdef CONFIG_DIFFTEST_SQUASH
120-
,
121-
probe.stamp
104+
,
105+
probe.stamp
122106
#endif // CONFIG_DIFFTEST_SQUASH
123-
};
124-
state->store_event_queue.push(storeCommit);
107+
};
108+
state->store_event_queue.push(storeCommitHigh);
109+
}
125110
}
126111
} else if (probe.wLine) {
127112
uint64_t blockAddr = addr >> BLOCKOFFSETBITS << BLOCKOFFSETBITS;

0 commit comments

Comments
 (0)