Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / memsync / src / MemoryAccessHistory.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: MemoryAccessHistory.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21/************************************************************************
22**
23** Copyright (C) 2002, Sun Microsystems, Inc.
24**
25** Sun considers its source code as an unpublished, proprietary
26** trade secret and it is available only under strict license provisions.
27** This copyright notice is placed here only to protect Sun in the event
28** the source is deemed a published work. Disassembly, decompilation,
29** or other means of reducing the object code to human readable form
30** is prohibited by the license agreement under which this code is
31** provided to the user or company in possession of this copy."
32**
33*************************************************************************/
34#include "MemoryAccessHistory.h"
35#include <sstream>
36#include <utility>
37
38using namespace std;
39using namespace Tso;
40////////////////////////////////////////////////
41
42MemoryAccessHistory::MemoryAccessHistory()
43{
44
45}
46
47////////////////////////////////////////////////
48
49MemoryAccessHistory::MemoryAccessHistory( const MemoryAccessHistory & orig )
50{
51 hist_ = orig.hist_;
52}
53
54////////////////////////////////////////////////
55
56MemoryAccessHistory::~MemoryAccessHistory()
57{
58
59}
60
61////////////////////////////////////////////////
62
63const MemoryAccessHistory &
64MemoryAccessHistory::operator=( const MemoryAccessHistory & rhs )
65{
66
67
68 return *this;
69}
70
71////////////////////////////////////////////////
72
73bool
74MemoryAccessHistory::operator==( const MemoryAccessHistory & rhs ) const
75{
76
77 return false;
78}
79
80////////////////////////////////////////////////
81
82string
83MemoryAccessHistory::toString() const
84{
85 map<uint64_t,MemoryAccessHistoryItem>::const_iterator ii;
86 ostringstream os;
87
88 os << "MemoryAccessHistory (size=" << hist_.size() << ")" << endl;
89 for (ii = hist_.begin(); ii != hist_.end(); ii++) {
90 const MemoryAccessHistoryItem& mahi = ii->second;
91 os << mahi.toString();
92 }
93 return os.str();
94}
95
96void
97MemoryAccessHistory::storeCommit (TsoNode* storeNode)
98{
99 pair<map<uint64_t,MemoryAccessHistoryItem>::iterator,bool> p;
100 map<uint64_t,MemoryAccessHistoryItem>::iterator ii;
101 MemoryAccessHistoryItem* mahItemPtr;
102 list<TsoNode*>::iterator ni;
103 TsoNode* loadNode;
104 TsoEdge edge;
105 uint64_t addr = storeNode->getAddr();
106 uint64_t data = storeNode->getData();
107 uint8_t sizeV = storeNode->getSizeV();
108 uint8_t bmask = 0x80;
109 int bsft = 56;
110
111 addr = addr & ADDR_MASK;
112 for (int i = 0; i < 8; i++, bmask >>= 1, addr++) {
113 if (sizeV & bmask) {
114 ii = hist_.find(addr);
115 if (ii == hist_.end()) { // insert a new one
116 mahItemPtr = new MemoryAccessHistoryItem();
117 mahItemPtr->setAddr(addr);
118 mahItemPtr->setData((data >> (bsft - i*8)) & 0xffull);
119 p = hist_.insert(make_pair(addr, *mahItemPtr));
120 assert (p.second);
121 ii = p.first;
122 }
123
124 /* form anti-dependence edges */
125 MemoryAccessHistoryItem& mahi = ii->second;
126 mahi.setData((data >> (bsft - i*8)) & 0xffull); // update data
127
128 for (ni = mahi.ldNodeBegin(); ni != mahi.ldNodeEnd(); ni++) {
129 loadNode = *ni;
130 if (loadNode != storeNode) { // exclude atomic node
131 edge.addEdge (ET_ANTI, loadNode, storeNode);
132 }
133 }
134 mahi.ldNodeClear(); // clear the flow dependence list
135
136 /* new storeNode's global observed order idx becomes previous node's retire */
137 if (mahi.stNodeSize() > 0) {
138 ni = mahi.stNodeBegin();
139 (*ni)->setRetire(storeNode->getGobs());
140 (*ni)->orOld(bmask);
141 edge.addEdge (ET_OUTPUT, (*ni), storeNode);
142 }
143
144 mahi.stNodePushFront(storeNode);
145 MSYNC_DEBUG(6, "MAH Push %s",(*(mahi.stNodeBegin()))->toString().c_str());
146 }
147 }
148
149 MSYNC_DEBUG(8, "%s", toString().c_str());
150}
151
152void
153MemoryAccessHistory::loadAccess (TsoNode* loadNode)
154{
155 map<uint64_t, MemoryAccessHistoryItem>::iterator ii;
156 list<TsoNode*>::iterator ni;
157 TsoEdge edge;
158 uint64_t addr = loadNode->getAddr();
159 uint8_t sizeV = loadNode->getSizeV();
160 uint8_t bmask = 0x80;
161
162 if (hist_.size() == 0) return;
163
164 MSYNC_DEBUG(8, "%s", toString().c_str());
165
166 addr = addr & ADDR_MASK;
167 for (int i = 0; i < 8; i++, bmask >>= 1, addr++) {
168 if (sizeV & bmask) {
169 ii = hist_.find(addr);
170 if (ii != hist_.end()) {
171
172 MemoryAccessHistoryItem& mahi = ii->second;
173
174 MSYNC_DEBUG(8, "Found the node (i=%d) %s", i, mahi.toString().c_str());
175
176 ni = mahi.stNodeBegin();
177
178 for (; ni != mahi.stNodeEnd(); ni++) {
179
180 if (loadNode->getCommit() >= (*ni)->getCommit()) {
181 if (ni == mahi.stNodeBegin()) { // ldNodeList_ contains only flow-dependent load
182 mahi.ldNodePushFront(loadNode); // to the head stNodeList_ node
183 }
184 edge.addEdge(ET_FLOW, *ni, loadNode);
185 if (ni != mahi.stNodeBegin()) {
186 ni--;
187 edge.addEdge(ET_ANTI, loadNode, *ni);
188 }
189 break;
190 }
191 }
192 } else {
193 MSYNC_DEBUG(8, "Not Found the node (i=%d)", i);
194 }
195 }
196 }
197}
198
199void
200MemoryAccessHistory::removeStoreNode (TsoNode* storeNodeP)
201{
202 pair<map<uint64_t,MemoryAccessHistoryItem>::iterator,bool> p;
203 map<uint64_t,MemoryAccessHistoryItem>::iterator ii;
204 list<TsoNode*>::iterator ni;
205 TsoNode* loadNodeP;
206 TsoEdge edge;
207 uint64_t addr = storeNodeP->getAddr();
208 uint64_t data = storeNodeP->getData();
209 uint8_t sizeV = storeNodeP->getSizeV();
210 uint8_t bmask = 0x80;
211 int bsft = 56;
212
213 addr = addr & ADDR_MASK;
214 for (int i = 0; i < 8; i++, bmask >>= 1, addr++) {
215 if (sizeV & bmask) {
216 ii = hist_.find(addr);
217 if (ii == hist_.end())
218 {
219 MS_ERROR("Removed storeNode's MAP missing in MemoryAccess History. PA=%llx", addr);
220 return;
221 }
222 MemoryAccessHistoryItem& mahi = ii->second;
223 for (ni = mahi.stNodeBegin(); ni != mahi.stNodeEnd(); ni++) {
224 if (*ni == storeNodeP) {
225 if (ni == mahi.stNodeBegin())
226 {
227 MS_ERROR("Removed storeNode matches with the 1st in the list. PA=%llx", addr);
228 return;
229 }
230 mahi.stNodeErase(ni);
231 break;
232 }
233 }
234 }
235 }
236}