Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / regdef / RegisterArray.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: RegisterArray.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#include <iostream>
22#include <stdlib.h>
23#include <assert.h>
24#include "Object.h"
25#include "RegisterArray.h"
26#include "Signature.h"
27using namespace std;
28
29RegisterArray::RegisterArray (string n, Block *b, Addr a, uint c,
30 Addr s, uint w) :
31 valueR(n, NULL, a, w)
32{
33 assert(b != NULL);
34 assert(w == 1 || w == 2 || w == 4 || w == 8);
35 assert((a % w) == 0);
36 assert(c > 0);
37 assert(s > 0 && (s % w) == 0);
38
39 baseName = n;
40 fullName = b->getFullName() + "." + n;
41 block = b;
42
43 startAddr = a;
44 endAddr = a + (c - 1) * s;
45 count = c;
46 step = s;
47
48 regType = NULL; // no RegisterType yet
49 regState = new RegisterState[count]; // undefined value
50 regInfo = new RegisterInfo[count]; // unassigned and dirty
51 mySignature = NULL; // allocated lazily
52
53 reinitRegister(&valueR);
54
55 b->addRegisterArray(this);
56}
57
58RegisterArray::~RegisterArray ()
59{
60 delete regType;
61 delete[] regState;
62 delete[] regInfo;
63 if (mySignature) {
64 for (uint i=0; i<count; i++)
65 delete mySignature[i];
66 delete[] mySignature;
67 }
68}
69
70void RegisterArray::printThis (ostream &os)
71{
72 assert(regType != NULL);
73
74 os << getFullName() << " (0x" << hex << startAddr << " to 0x" << endAddr
75 << ", count " << dec << count << ", step 0x" << hex << step
76 << ", width " << dec << regType->widthBytes << " bytes)\n" << dec;
77
78 if (isSmall()) {
79 for (uint index=0; index<count; index++) {
80 Register *reg = &(*this)[index];
81 reg->printThis(os);
82 }
83 }
84}
85
86void RegisterArray::resetThis ()
87{
88 assert(regType != NULL);
89
90 regType->check(getFullName());
91
92 if (regType->resetValue == 0)
93 memset(regState, 0, sizeof(RegisterState) * count);
94 else
95 for (uint index=0; index<count; index++)
96 regState[index].value = regType->resetValue;
97
98 if (regType->resetAssigned == 0)
99 memset(regInfo, 0, sizeof(RegisterInfo) * count);
100 else
101 for (uint index=0; index<count; index++) {
102 regInfo[index].assigned = (regType->resetAssigned != 0);
103 regInfo[index].clean = false;
104 }
105}
106
107void RegisterArray::signThis (ofstream &ofs)
108{
109 assert(regType != NULL);
110
111 regType->check(getFullName());
112
113 if (mySignature == NULL) {
114 mySignature = new Signature*[count];
115
116 for (uint i=0; i<count; i++) {
117 mySignature[i] = NULL;
118 }
119 }
120
121 Signature::signScopeBegin(ofs, getFullName());
122
123 for (uint index=0; index<count; index++) {
124 ostringstream o;
125 o << index;
126 string s = "[" + o.str() + "]";
127 string n = getBaseName() + s;
128 string f = getFullName() + s;
129 mySignature[index] = new Signature;
130 mySignature[index]->add(new SignData(f, "", &regState[index].value));
131 mySignature[index]->sign(ofs, n, "Register");
132 }
133
134 Signature::signScopeClose(ofs, getFullName());
135}
136
137void RegisterArray::traceThis (ofstream &ofs)
138{
139 for (uint index=0; index<count; index++) {
140 if (mySignature && mySignature[index] && !regInfo[index].clean) {
141 mySignature[index]->printThis(ofs);
142 regInfo[index].clean = true;
143 }
144 }
145}
146
147bool RegisterArray::lookup (Addr a, uint *i)
148{
149 if (a >= startAddr &&
150 a <= endAddr &&
151 (a - startAddr) % step == 0) {
152 uint64 index = (a - startAddr) / step;
153 assert(index < count);
154 if (i != NULL)
155 *i = uint(index);
156 return true;
157 }
158 else
159 return false;
160}
161
162Register &RegisterArray::operator[] (uint index)
163{
164 bindRegisterToIndex(&valueR, index);
165
166 return valueR; // return Register value by reference
167}
168
169void RegisterArray::reinitRegister (Register *r)
170{
171 assert(r != NULL);
172 assert(r->regType != NULL);
173
174 if (regType != NULL)
175 delete regType;
176
177 regType = r->regType; // set array regType to instance regType
178
179 delete r->regInfo; // clear out register pointers
180 delete r->regState;
181 r->regInfo = NULL;
182 r->regState = NULL;
183 r->derived = true; // do not delete dynamic state in ~Register
184}
185
186void RegisterArray::bindRegisterToIndex (Register *r, uint index)
187{
188 assert(regType != NULL);
189 assert(index < count);
190
191 Signature *signature = NULL;
192 if (mySignature != NULL)
193 signature = mySignature[index];
194
195 r->init(block, startAddr + step * index, true, index,
196 regType, &regState[index], &regInfo[index], signature);
197}