Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / regdef / include / RegisterArray.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: RegisterArray.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 ============================================
*/
#ifndef __RegisterArray_h
#define __RegisterArray_h
#include <stddef.h>
#include <assert.h>
#include <iostream>
#include <fstream>
#include <string>
#include "Block.h"
#include "Object.h"
#include "Datatype.h"
#include "Signature.h"
#include "Register.h"
using namespace std;
/** @file RegisterArray.h
* RegisterArray.h provides a set of classes for representing arrays
* of registers.
*
* @see RegisterArrayModule
*/
/** @defgroup RegisterArrayModule The RegisterArray Module
*
* Registers are 8, 16, 32 or 64 bits wide, and are composed of Fields.
* Fields are contiguous collections of bits within a Register. The value
* of a Register can be accessed at the Register level or at the
* Field level. Care is taken to ensure that large arrays of 64-bit registers
* are implemented efficiently - in terms of memory usage and run-time
* cost. Note that there is significant waste in the storage of narrower
* registers since they are held in 64-bit containers (with unused upper bits
* always zero).
*
* The classes and types defined here are:
* - RegisterArray
* - RegisterArrayOf
*
* The "public" interface provided by this file are RegisterArray
* and RegisterArrayOf. RegisterArray is used to form arrays of
* Register instances, and forms the base class for RegisterArrayOf.
* RegisterArrayOf<T> is a template class and represents an array
* of type T, where T is a subclass of Register. This is the more
* useful class since the standard way of describing a specific
* kind of Register is to subclass the Register class and add
* appropriate fields. The RegisterArrayOf class is designed to
* have the following properties:
* - support a natural syntax for accessing array elements
* - be storage efficient, it does not allocate an array of Register
* instances since this adds a lot of overhead. Instead the array
* is carefully constructed out of RegisterState, RegisterInfo
* and RegisterType instances.
* - to support efficient indexing of the array to an element.
* - to maintain the correct subclass for elements in the array.
* This is important to ensure that Field instances and virtual
* methods of the Register subclass are correctly propagated.
*
* The following syntax can be used to access an element in a
* RegisterArrayOf<T> at the Register and Field level:
* - arrayname[index].get() to get the whole Register
* - arrayname[index].set() to set the whole Register
* - arrayname[index].fieldname.get() to get a Field
* - arrayname[index].fieldname.set() to get a Field
*
* See also Register.h
*
* @{
*/
/** RegisterArray is used to constructs arrays of registers,
* and index into the array to a Register element. All registers in the
* array are systematically named, have the same RegisterType, belong to
* the same Block and are assigned an address using a base address and a
* step value.
*/
class RegisterArray
{
public:
/** Constructor for RegisterArray.
* @param n the basename for this RegisterArray. The basename of a
* Register in the array will be this basename appended by
* "[i]" where i is the index of that Register in the array.
* @param b a pointer to the Block with which this RegisterArray is
* associated. The fullname of this RegisterArray and its
* Registers are scoped within that Block.
* @param a the base address of this RegisterArray.
* @param c the number of registers in this RegisterArray.
* @param s the step between addresses for registers in this
* RegisterArray. The step must be greater than 0, and an
* exact integral multiple of the width.
* @param w the width of each register in bytes, defaults to 8 bytes.
*
* The address of the Register with index i is given by a + (i * s).
*/
RegisterArray(string n, Block *b, Addr a, uint c=1,
Addr s=Addr(8), uint w=8);
/** Destructor for RegisterArray. This is virtual so that the appropriate
* destructor for any derived class is used. */
virtual ~RegisterArray();
/** Get the basename for this RegisterArray. */
string getBaseName() const { return baseName; }
/** Get the fullname for this RegisterArray. */
string getFullName() const { return fullName; }
/** Get the start address for this RegisterArray. */
Addr getStartAddr() const { return startAddr; }
/** Get the end address for this RegisterArray. */
Addr getEndAddr() const { return endAddr; }
/** Get the number of element in this RegisterArray. */
uint getCount() const { return count; }
/** Get the step between addresses in this RegisterArray. */
Addr getStep() const { return step; }
/** Get the width in bytes of each register in this RegisterArray. */
uint getWidth() const { return regType->widthBytes; }
/** Lookup a register in this RegisterArray by its address.
* @param a the address to look-up.
* @param i if the address matches a register and i is not the NULL
* pointer, then the index of that Register in the array
* will be copied into *i. This index can subsequently
* be used to index into the RegisterArray to find the
* Register instance. If i is NULL the index is not returned;
* this can be useful when checking whether an address matches
* an element in a register array.
* @return returns true if the address matches a register in this
* RegisterArray, otherwise false.
*/
bool lookup(Addr a, uint *i = NULL);
/** Get the address of a Register in this RegisterArray.
* @param index the index of a Register in this RegisterArray.
* @return the address of the Register with that index.
*/
Addr getAddr(uint index) const
{
assert(index < count);
return startAddr + step * index;
}
/** Return true if this is a small RegisterArray, otherwise false.
* The break-points are somewhat arbitrary. This classification is
* used as follows:
* - small: trace enabled, print enabled, map enabled.
* - large: trace disabled, print disabled, map enabled.
* - huge: trace disabled, print disabled, map disabled.
*/
bool isSmall() const { return count <= 64; }
/** Return true if this is a large RegisterArray, otherwise false.
* The break-points are somewhat arbitrary. This classification is
* used as follows:
* - small: trace enabled, print enabled, map enabled.
* - large: trace disabled, print disabled, map enabled.
* - huge: trace disabled, print disabled, map disabled.
*/
bool isLarge() const { return count > 64 && count <= 1024; }
/** Return true if this is a huge RegisterArray, otherwise false.
* The break-points are somewhat arbitrary. This classification is
* used as follows:
* - small: trace enabled, print enabled, map enabled.
* - large: trace disabled, print disabled, map enabled.
* - huge: trace disabled, print disabled, map disabled.
*/
bool isHuge() const { return count > 1024; }
/** Enable write Block-level call-backs for this RegisterArray. */
void enableWriteBlockCB()
{
assert(block != NULL);
regType->writeBlockCB = true;
}
/** Disable write Block-level call-backs for this RegisterArray. */
void disableWriteBlockCB()
{
regType->writeBlockCB = false;
}
/** Enable read Block-level call-backs for this RegisterArray. */
void enableReadBlockCB()
{
assert(block != NULL);
regType->readBlockCB = true;
}
/** Disable read Block-level call-backs for this RegisterArray. */
void disableReadBlockCB()
{
regType->readBlockCB = false;
}
/** Print this RegisterArray to the specified output stream - note
* that the values will not be printed for any large RegisterArray.
*/
void printThis(ostream &os);
/** Reset this RegisterArray to its initial value. */
void resetThis();
/** Create the Signature for this RegisterArray so that it can
* subsequently be traced.
* @param ofs the output file stream.*/
void signThis(ofstream &ofs);
/** Trace this RegisterArray to the specified output stream.
* @param ofs the output file stream.*/
void traceThis(ofstream &ofs);
/** Index operator for RegisterArray. This indexes into the
* RegisterArray and returns the Register instance at the
* specified index by *reference*. This method is virtual
* to allow over-riding by sub-classes (e.g. RegisterArrayOf).
* @param index the index into the RegisterArray. */
virtual Register &operator[](uint index);
protected:
void reinitRegister(Register *r);
void bindRegisterToIndex(Register *r, uint index);
private:
string baseName;
string fullName;
Block *block;
Addr startAddr;
Addr endAddr;
uint count;
Addr step;
RegisterType *regType;
RegisterState *regState;
RegisterInfo *regInfo;
Signature **mySignature;
Register valueR;
};
/** RegisterArrayOf is used to constructs arrays of registers, and index into
* the array to a Register element. All registers in the array are
* systematically named, have the same RegisterType, belong to the same
* Block and are assigned an address using a base address and a step value.
* RegisterArrayOf is a template class where the template parameter
* specifies the Register class of which the array is constructed.
*
* The class T must be derived from Register and must provide a constructor
* of the form:
* T::T(Block *b)
*
*/
template<class T> class RegisterArrayOf : public RegisterArray
{
public:
/** Constructor for RegisterArrayOf.
* @param n the basename for this RegisterArrayOf. The basename of a
* Register in the array will be this basename appended by
* "[i]" where i is the index of that Register in the array.
* @param b a pointer to the Block with which this RegisterArrayOf is
* associated. The fullname of this RegisterArrayOf and its
* Registers are scoped within that Block.
* @param a the base address of this RegisterArrayOf.
* @param c the number of registers in this RegisterArrayOf.
* @param s the step between addresses for registers in this
* RegisterArrayOf. The step must be greater than 0, and an
* exact integral multiple of the width.
* @param w the width of each register in bytes, defaults to 8 bytes.
*
* The address of the Register with index i is given by a + (i * s).
*/
RegisterArrayOf(string n, Block *b, Addr a, uint c=1,
Addr s=Addr(8), uint w=8);
/** Index operator for RegisterArrayOf. This indexes into the
* RegisterArrayOf and returns the instance of type T at the specified
* index by *reference*.
* @param index the index into the RegisterArrayOf. */
T &operator[](uint index);
private:
T valueT;
};
/** @} */
#include "pRegisterArray.h"
#endif