Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / memsync / src / MemoryAccessHistory.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: MemoryAccessHistory.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
/************************************************************************
**
** Copyright (C) 2002, Sun Microsystems, Inc.
**
** Sun considers its source code as an unpublished, proprietary
** trade secret and it is available only under strict license provisions.
** This copyright notice is placed here only to protect Sun in the event
** the source is deemed a published work. Disassembly, decompilation,
** or other means of reducing the object code to human readable form
** is prohibited by the license agreement under which this code is
** provided to the user or company in possession of this copy."
**
*************************************************************************/
#include "MemoryAccessHistory.h"
#include <sstream>
#include <utility>
using namespace std;
using namespace Tso;
////////////////////////////////////////////////
MemoryAccessHistory::MemoryAccessHistory()
{
}
////////////////////////////////////////////////
MemoryAccessHistory::MemoryAccessHistory( const MemoryAccessHistory & orig )
{
hist_ = orig.hist_;
}
////////////////////////////////////////////////
MemoryAccessHistory::~MemoryAccessHistory()
{
}
////////////////////////////////////////////////
const MemoryAccessHistory &
MemoryAccessHistory::operator=( const MemoryAccessHistory & rhs )
{
return *this;
}
////////////////////////////////////////////////
bool
MemoryAccessHistory::operator==( const MemoryAccessHistory & rhs ) const
{
return false;
}
////////////////////////////////////////////////
string
MemoryAccessHistory::toString() const
{
map<uint64_t,MemoryAccessHistoryItem>::const_iterator ii;
ostringstream os;
os << "MemoryAccessHistory (size=" << hist_.size() << ")" << endl;
for (ii = hist_.begin(); ii != hist_.end(); ii++) {
const MemoryAccessHistoryItem& mahi = ii->second;
os << mahi.toString();
}
return os.str();
}
void
MemoryAccessHistory::storeCommit (TsoNode* storeNode)
{
pair<map<uint64_t,MemoryAccessHistoryItem>::iterator,bool> p;
map<uint64_t,MemoryAccessHistoryItem>::iterator ii;
MemoryAccessHistoryItem* mahItemPtr;
list<TsoNode*>::iterator ni;
TsoNode* loadNode;
TsoEdge edge;
uint64_t addr = storeNode->getAddr();
uint64_t data = storeNode->getData();
uint8_t sizeV = storeNode->getSizeV();
uint8_t bmask = 0x80;
int bsft = 56;
addr = addr & ADDR_MASK;
for (int i = 0; i < 8; i++, bmask >>= 1, addr++) {
if (sizeV & bmask) {
ii = hist_.find(addr);
if (ii == hist_.end()) { // insert a new one
mahItemPtr = new MemoryAccessHistoryItem();
mahItemPtr->setAddr(addr);
mahItemPtr->setData((data >> (bsft - i*8)) & 0xffull);
p = hist_.insert(make_pair(addr, *mahItemPtr));
assert (p.second);
ii = p.first;
}
/* form anti-dependence edges */
MemoryAccessHistoryItem& mahi = ii->second;
mahi.setData((data >> (bsft - i*8)) & 0xffull); // update data
for (ni = mahi.ldNodeBegin(); ni != mahi.ldNodeEnd(); ni++) {
loadNode = *ni;
if (loadNode != storeNode) { // exclude atomic node
edge.addEdge (ET_ANTI, loadNode, storeNode);
}
}
mahi.ldNodeClear(); // clear the flow dependence list
/* new storeNode's global observed order idx becomes previous node's retire */
if (mahi.stNodeSize() > 0) {
ni = mahi.stNodeBegin();
(*ni)->setRetire(storeNode->getGobs());
(*ni)->orOld(bmask);
edge.addEdge (ET_OUTPUT, (*ni), storeNode);
}
mahi.stNodePushFront(storeNode);
MSYNC_DEBUG(6, "MAH Push %s",(*(mahi.stNodeBegin()))->toString().c_str());
}
}
MSYNC_DEBUG(8, "%s", toString().c_str());
}
void
MemoryAccessHistory::loadAccess (TsoNode* loadNode)
{
map<uint64_t, MemoryAccessHistoryItem>::iterator ii;
list<TsoNode*>::iterator ni;
TsoEdge edge;
uint64_t addr = loadNode->getAddr();
uint8_t sizeV = loadNode->getSizeV();
uint8_t bmask = 0x80;
if (hist_.size() == 0) return;
MSYNC_DEBUG(8, "%s", toString().c_str());
addr = addr & ADDR_MASK;
for (int i = 0; i < 8; i++, bmask >>= 1, addr++) {
if (sizeV & bmask) {
ii = hist_.find(addr);
if (ii != hist_.end()) {
MemoryAccessHistoryItem& mahi = ii->second;
MSYNC_DEBUG(8, "Found the node (i=%d) %s", i, mahi.toString().c_str());
ni = mahi.stNodeBegin();
for (; ni != mahi.stNodeEnd(); ni++) {
if (loadNode->getCommit() >= (*ni)->getCommit()) {
if (ni == mahi.stNodeBegin()) { // ldNodeList_ contains only flow-dependent load
mahi.ldNodePushFront(loadNode); // to the head stNodeList_ node
}
edge.addEdge(ET_FLOW, *ni, loadNode);
if (ni != mahi.stNodeBegin()) {
ni--;
edge.addEdge(ET_ANTI, loadNode, *ni);
}
break;
}
}
} else {
MSYNC_DEBUG(8, "Not Found the node (i=%d)", i);
}
}
}
}
void
MemoryAccessHistory::removeStoreNode (TsoNode* storeNodeP)
{
pair<map<uint64_t,MemoryAccessHistoryItem>::iterator,bool> p;
map<uint64_t,MemoryAccessHistoryItem>::iterator ii;
list<TsoNode*>::iterator ni;
TsoNode* loadNodeP;
TsoEdge edge;
uint64_t addr = storeNodeP->getAddr();
uint64_t data = storeNodeP->getData();
uint8_t sizeV = storeNodeP->getSizeV();
uint8_t bmask = 0x80;
int bsft = 56;
addr = addr & ADDR_MASK;
for (int i = 0; i < 8; i++, bmask >>= 1, addr++) {
if (sizeV & bmask) {
ii = hist_.find(addr);
if (ii == hist_.end())
{
MS_ERROR("Removed storeNode's MAP missing in MemoryAccess History. PA=%llx", addr);
return;
}
MemoryAccessHistoryItem& mahi = ii->second;
for (ni = mahi.stNodeBegin(); ni != mahi.stNodeEnd(); ni++) {
if (*ni == storeNodeP) {
if (ni == mahi.stNodeBegin())
{
MS_ERROR("Removed storeNode matches with the 1st in the list. PA=%llx", addr);
return;
}
mahi.stNodeErase(ni);
break;
}
}
}
}
}