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+
2337bool 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