Address.hh revision 6145
1 2/* 3 * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin 4 * Multifacet Project. ALL RIGHTS RESERVED. 5 * 6 * ##HEADER## 7 * 8 * This software is furnished under a license and may be used and 9 * copied only in accordance with the terms of such license and the 10 * inclusion of the above copyright notice. This software or any 11 * other copies thereof or any derivative works may not be provided or 12 * otherwise made available to any other persons. Title to and 13 * ownership of the software is retained by Mark Hill and David Wood. 14 * Any use of this software must include the above copyright notice. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO 17 * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE. 18 * */ 19 20/* 21 * $Id$ 22 */ 23 24#ifndef ADDRESS_H 25#define ADDRESS_H 26 27#include <iomanip> 28#include "Global.hh" 29#include "RubyConfig.hh" 30#include "NodeID.hh" 31#include "MachineID.hh" 32 33const int ADDRESS_WIDTH = 64; // address width in bytes 34 35class Address; 36typedef Address PhysAddress; 37typedef Address VirtAddress; 38 39class Address { 40public: 41 // Constructors 42 Address() { m_address = 0; } 43 explicit Address(physical_address_t address) { m_address = address; } 44 45 Address(const Address& obj); 46 Address& operator=(const Address& obj); 47 48 // Destructor 49 // ~Address(); 50 51 // Public Methods 52 53 void setAddress(physical_address_t address) { m_address = address; } 54 physical_address_t getAddress() const {return m_address;} 55 // selects bits inclusive 56 physical_address_t bitSelect(int small, int big) const; 57 physical_address_t maskLowOrderBits(int number) const; 58 physical_address_t maskHighOrderBits(int number) const; 59 physical_address_t shiftLowOrderBits(int number) const; 60 physical_address_t getLineAddress() const 61 { return bitSelect(RubyConfig::dataBlockBits(), ADDRESS_WIDTH); } 62 physical_address_t getOffset() const 63 { return bitSelect(0, RubyConfig::dataBlockBits()-1); } 64 65 void makeLineAddress() { m_address = maskLowOrderBits(RubyConfig::dataBlockBits()); } 66 // returns the next stride address based on line address 67 void makeNextStrideAddress( int stride) { 68 m_address = maskLowOrderBits(RubyConfig::dataBlockBits()) 69 + RubyConfig::dataBlockBytes()*stride; 70 } 71 void makePageAddress() { m_address = maskLowOrderBits(RubyConfig::pageSizeBits()); } 72 int getBankSetNum() const; 73 int getBankSetDist() const; 74 75 Index memoryModuleIndex() const; 76 77 void print(ostream& out) const; 78 void output(ostream& out) const; 79 void input(istream& in); 80 81 void setOffset( int offset ){ 82 // first, zero out the offset bits 83 makeLineAddress(); 84 m_address |= (physical_address_t) offset; 85 } 86 87private: 88 // Private Methods 89 90 // Private copy constructor and assignment operator 91 // Address(const Address& obj); 92 // Address& operator=(const Address& obj); 93 94 // Data Members (m_ prefix) 95 physical_address_t m_address; 96}; 97 98inline 99Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } 100 101inline 102Address next_stride_address(const Address& addr, int stride) { 103 Address temp = addr; 104 temp.makeNextStrideAddress(stride); 105 temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem 106 return temp; 107} 108 109inline 110Address page_address(const Address& addr) { Address temp(addr); temp.makePageAddress(); return temp; } 111 112// Output operator declaration 113ostream& operator<<(ostream& out, const Address& obj); 114// comparison operator declaration 115bool operator==(const Address& obj1, const Address& obj2); 116bool operator!=(const Address& obj1, const Address& obj2); 117bool operator<(const Address& obj1, const Address& obj2); 118/* Address& operator=(const physical_address_t address); */ 119 120inline 121bool operator<(const Address& obj1, const Address& obj2) 122{ 123 return obj1.getAddress() < obj2.getAddress(); 124} 125 126// ******************* Definitions ******************* 127 128// Output operator definition 129inline 130ostream& operator<<(ostream& out, const Address& obj) 131{ 132 obj.print(out); 133 out << flush; 134 return out; 135} 136 137inline 138bool operator==(const Address& obj1, const Address& obj2) 139{ 140 return (obj1.getAddress() == obj2.getAddress()); 141} 142 143inline 144bool operator!=(const Address& obj1, const Address& obj2) 145{ 146 return (obj1.getAddress() != obj2.getAddress()); 147} 148 149inline 150physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive 151{ 152 physical_address_t mask; 153 assert(big >= small); 154 155 if (big >= ADDRESS_WIDTH - 1) { 156 return (m_address >> small); 157 } else { 158 mask = ~((physical_address_t)~0 << (big + 1)); 159 // FIXME - this is slow to manipulate a 64-bit number using 32-bits 160 physical_address_t partial = (m_address & mask); 161 return (partial >> small); 162 } 163} 164 165inline 166physical_address_t Address::maskLowOrderBits(int number) const 167{ 168 physical_address_t mask; 169 170 if (number >= ADDRESS_WIDTH - 1) { 171 mask = ~0; 172 } else { 173 mask = (physical_address_t)~0 << number; 174 } 175 return (m_address & mask); 176} 177 178inline 179physical_address_t Address::maskHighOrderBits(int number) const 180{ 181 physical_address_t mask; 182 183 if (number >= ADDRESS_WIDTH - 1) { 184 mask = ~0; 185 } else { 186 mask = (physical_address_t)~0 >> number; 187 } 188 return (m_address & mask); 189} 190 191inline 192physical_address_t Address::shiftLowOrderBits(int number) const 193{ 194 return (m_address >> number); 195} 196 197inline 198integer_t Address::memoryModuleIndex() const 199{ 200 integer_t index = bitSelect(RubyConfig::dataBlockBits()+RubyConfig::memoryBits(), ADDRESS_WIDTH); 201 assert (index >= 0); 202 if (index >= RubyConfig::memoryModuleBlocks()) { 203 cerr << " memoryBits: " << RubyConfig::memoryBits() << " memorySizeBits: " << RubyConfig::memorySizeBits() 204 << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush 205 << "error: limit exceeded. " << 206 " dataBlockBits: " << RubyConfig::dataBlockBits() << 207 " memoryModuleBlocks: " << RubyConfig::memoryModuleBlocks() << 208 " index: " << index << endl; 209 } 210 assert (index < RubyConfig::memoryModuleBlocks()); 211 return index; 212 213 // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); 214 // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1); 215 216 //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); 217 218 /* 219 Round-robin mapping of addresses, at page size granularity 220 221ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS 222 | | | | 223 \ / \ / \ / \ / 0 224 ----------------------------------------------------------------------- 225 | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 226 | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 227 ----------------------------------------------------------------------- 228 indexHighPortion indexLowPortion 229 <-------> 230 NUMBER_OF_MEMORY_MODULE_BITS 231 */ 232} 233 234inline 235void Address::print(ostream& out) const 236{ 237 out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush; 238} 239 240class Address; 241namespace __gnu_cxx { 242 template <> struct hash<Address> 243 { 244 size_t operator()(const Address &s) const { return (size_t) s.getAddress(); } 245 }; 246} 247namespace std { 248 template <> struct equal_to<Address> 249 { 250 bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; } 251 }; 252} 253 254#endif //ADDRESS_H 255 256