* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: TsoNode.h
* 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 "MemorySyncDefs.h"
#include "TsoCheckerDefs.h"
#include "TsoCheckerCmd.h"
TsoNode(const TsoCheckerCmd
& cmd
);
* @param orig The TsoNode object to copy.
TsoNode( const TsoNode
&orig
);
* @param rhs The right hand side of the equality operator
* @return Return true if this objec and rhs are equal,
bool operator==( const TsoNode
&rhs
) const;
* @param rhs The right hand side of the assignment operator.
* @return The lvalue of the assignment.
const TsoNode
& operator=( const TsoNode
&rhs
);
* Return a string representation of this TsoNode object.
std::string
toString() const;
* Remove all edge pointers in the in_ list. The function also removes the
* edge pointer in the edge's source node's out_ list.
* Remove all edge pointers in the out_ list. The function also removes the
* edge pointer in the edge's destination node's in_ list.
* Remove all edge pointers in the in_ & out_ list. This method calls
* removeInEdges() and removeOutEdges().
* Check to see if all nodes corresponding to the node's instructions has
* @return a boolean to relect this check
* Check to see if the node coresponds to a store instruction
* Note that atomic is also counted as a store instruction.
* @return a boolean to relect this check
isStore() { return (itype_
== ITYPE_STORE
||
itype_
== ITYPE_BLOCK_STORE
||
itype_
== ITYPE_STORE_INIT
||
itype_
== ITYPE_ATOMIC
); }
* Check to see if the node coresponds to a load instruction
* Note that atomic is also counted as a load instruction.
* @return a boolean to relect this check
isLoad() { return (itype_
== ITYPE_LOAD
||
itype_
== ITYPE_BLOCK_LOAD
||
itype_
== ITYPE_QUAD_LOAD
||
itype_
== ITYPE_DOUBLE_LOAD
||
itype_
== ITYPE_ATOMIC
); }
* Check to see if the node coresponds to a RMO instruction
* @return a boolean to relect this check
isRMO() { return (itype_
== ITYPE_BLOCK_STORE
||
itype_
== ITYPE_STORE_INIT
||
itype_
== ITYPE_BLOCK_LOAD
); }
* Check to see if the node coresponds to an atomic instruction
* @return a boolean to relect this check
isAtomic() { return (itype_
== ITYPE_ATOMIC
); }
* Check to see if the node's addres is in I/O range
* @return a boolean to relect this check
isIO() { return ((addr_
& IO_ADDR_BIT_MASK
) != 0); }
* Check to see if the node corresponds to a TSO load instruction
* A TSO load is defined as a load whose address is not in I/O space
isTsoLoad() { return (isLoad() && !isRMO() && !isIO()); }
* Check to see if the node corresponds to a TSO store instruction
* A TSO store is defined as a store whose address is not in I/O space
isTsoStore() { return (isStore() && !isRMO() && !isIO()); }
* Check to see if the node corresponds to a TSO instruction
* A TSO instruciton is defined as an instruction whose address is not
* in I/O space and is not a RMO instruction
isTSO() { return (isTsoLoad() || isTsoStore()); }
* Check the if the node is MEM_STORE_COMMIT
isStoreCommit() { return (cmd_
== MEM_STORE_COMMIT
); }
* Check the if the node is MEM_LOAD_DATA
isLoadData() { return (cmd_
== MEM_LOAD_DATA
); }
* Get the begin iterator of the in_ list
std::list
<TsoEdge
*>::iterator
inBegin() { return in_
.begin(); };
* Get the end iterator of the in_ list
std::list
<TsoEdge
*>::iterator
inEnd() { return in_
.end(); }
* Get the begin iterator of the out_ list
std::list
<TsoEdge
*>::iterator
outBegin() { return out_
.begin(); }
* Get the end iterator of the out_ list
std::list
<TsoEdge
*>::iterator
outEnd() { return out_
.end(); }
std::list
<TsoEdge
*>::size_type
inSize() { return in_
.size(); }
std::list
<TsoEdge
*>::size_type
outSize() { return out_
.size(); }
* Push an edge point to the front of the in_ list
* @param edge The edge pointer to be pushed
void inPushFront (TsoEdge
* edge
) { in_
.push_front(edge
); }
* Push an edge point to the front of the out_ list
* @param edge The edge pointer to be pushed
void outPushFront (TsoEdge
* edge
) { out_
.push_front(edge
); }
* @param ei The iterator whose corresponding entry is to be erase
void inErase(std::list
<TsoEdge
*>::iterator ei
) { in_
.erase(ei
); }
* @param ei The iterator whose corresponding entry is to be erase
void outErase(std::list
<TsoEdge
*>::iterator ei
) { out_
.erase(ei
); }
* Clear all entries in in_ list
void inClear() { in_
.clear(); }
* Clear all entries in out_ list
void outClear() { out_
.clear(); }
* Push a node pointer to the back of the nodes_ list
* @param np The node pointer to be pushed
void nodePush (TsoNode
* np
) { nodes_
.push_back(np
); };
/******************************************************************
* Private variable get/set methods
******************************************************************/
void setIseq (uint64_t iseq
) { iseq_
= iseq
; }
void setCommit (uint64_t commit
) { commit_
= commit
; }
void setGobs (uint64_t gobs
) { gobs_
= gobs
; }
void setRetire (uint64_t retire
) { retire_
= retire
; }
void setAddr (uint64_t addr
) { addr_
= addr
; }
void setData (uint64_t data
) { data_
= data
; }
void setNcnt (uint32_t ncnt
) { ncnt_
= ncnt
; }
void incNcnt () { ncnt_
++; }
void setThrdId (uint32_t tid
) { tid_
= tid
; }
void setItype (enum INSTR_TYPE itype
) { itype_
= itype
; }
void setCmd (enum MEM_CMD cmd
) { cmd_
= cmd
; }
void setNtype (enum MEM_CMD ntype
) { cmd_
= ntype
; }
void setDsrc (enum DATA_SRC dsrc
) { dsrc_
= dsrc
; }
void setSizeV (uint8_t sizeV
) { sizeV_
= sizeV
; }
void setOld (uint8_t old
) { old_
= old
; }
void orOld (uint8_t old
) { old_
= old_
| old
; }
void setLastStore (bool tf
) { lastStore_
= tf
; }
void setLastLoad (bool tf
) { lastLoad_
= tf
; }
char* getNodeName() { return nodeName_
; }
uint64_t getIseq() const { return iseq_
; }
uint64_t getCommit() const { return commit_
; }
uint64_t getGobs() const { return gobs_
; }
uint64_t getRetire() const { return retire_
; }
uint64_t getAddr() const { return addr_
; }
uint64_t getData() const { return data_
; }
uint32_t getNcnt() const { return ncnt_
; }
uint32_t getThrdId() const { return tid_
; }
enum INSTR_TYPE
getItype() const { return itype_
; }
enum MEM_CMD
getCmd() const { return cmd_
; }
enum MEM_CMD
getNtype() const { return cmd_
; }
enum DATA_SRC
getDsrc() const { return dsrc_
; }
uint8_t getSizeV() const { return sizeV_
; }
uint8_t getOld() const { return old_
; }
bool noInEdges() const { return (in_
.empty()); }
bool noOutEdges() const { return (out_
.empty()); }
bool hasInEdges() const { return (!in_
.empty()); }
bool hasOutEdges() const { return (!out_
.empty()); }
bool isAllOld() const { return ((sizeV_
^ old_
) == 0); }
bool isLastStore() const { return lastStore_
; }
bool isLastLoad() const { return lastLoad_
; }
* nodeName_, node's name, is used as the node lable in TSO digraph
* in_ contains the pointers of edges coming to this node
* out_ contains the pointers of edges coming from this node
std::list
<TsoEdge
*> out_
;
* nodes_ contains the pointers of nodes that belong to the same instruction as this node.
std::list
<TsoNode
*> nodes_
; // additional TSO nodes for atomic/quad load, block load/store
* iseq_ is the load/store instruction sequence, must consecutive
* but can be out-of-order
uint64_t iseq_
; // load/store instruction sequence number
* commit_ has different definitions for store and load. <br>
* For store it is the time when a store commits (for N2,
* it is the time when the data is written into L2 and can be seen
* by other L2 access). <br>
* For load, it is any time in the duration when the whole data can
* be seen in the L2 access. Note the source of a load may come from
* <p> This variable has the same meaning as macc_ in TsoCheckerCmd.h
* gobs_ is the global observed time of a store. Note that a store
* may have stale data in L1 caches of other cores, or caches of
* other chips. Before a store data can be globally observed, all
* those stale data must be either invalidated or be updated. <br>
* The gobs_ must be no earlier than its L2 commit time, commit_.
* retire_ is the time when the node can be retired. Note that different
* byte of data may have different retire time. This records the latest.
* addr_ is the physical address.
uint64_t addr_
; // address
* data_ is either the load data or store data.
* ncnt_ equals nnodes_.size() + 1 (itself)
* tid_ is a flat thread ID; each thread must have a unique ID.
uint32_t tid_
; // thread ID
* itype_ is the instruction type, such as load, store, block load/store,
* etc, whose definition is in
enum INSTR_TYPE itype_
; // instruction type
* cmd_ is the entry type, such as StoreCommit and LoadData, whose
enum MEM_CMD cmd_
; // command
* dsrc_ is the source of a load data, which could be L1, STB, or
enum DATA_SRC dsrc_
; // data source
* The data format is as follows: (Big Edian)
* +--------+--------+------------+--------+
* data | byte 0 | byte 1 | --- | byte 7 |
* (64 bits) +--------+--------+------------+--------+
* sizeV_: bit 7 bit 6 bit 0
* sizeV_ is to indicates which byte is valid: bit 0 for data_[7:0],
* bit 1 for data_[15:8], and so on.
uint8_t sizeV_
; // size vector: 1 -> valid byte
* old_ indicates if the corresponding byte of data in this node is old or not.
* Similar to sizeV_, bit 0 is the indicator of data_[7:0]; bit 1, data_[15:8],
uint8_t old_
; // bit vector: 1 -> old data in MemoryAccessHistory
* lastStore_ indicates if the node is the last store in the program order list,
* nodeList_ in TsoChecker.h, or not.
bool lastStore_
; // need both lastStore_ and lastLoad_ is because atomic
* lastStore_ indicates if the node is the last load in the program order list,
* nodeList_ in TsoChecker.h, or not.
bool lastLoad_
; // can have both