Address.hh revision 10466:73b7549d979e
1/*
2 * Copyright (c) 1999 Mark D. Hill and David A. Wood
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __MEM_RUBY_COMMON_ADDRESS_HH__
30#define __MEM_RUBY_COMMON_ADDRESS_HH__
31
32#include <cassert>
33#include <iomanip>
34#include <iostream>
35
36#include "base/hashmap.hh"
37#include "mem/ruby/common/TypeDefines.hh"
38
39const uint32_t ADDRESS_WIDTH = 64; // address width in bytes
40
41class Address;
42typedef Address PhysAddress;
43typedef Address VirtAddress;
44
45class Address
46{
47  public:
48    Address()
49        : m_address(0)
50    { }
51
52    explicit
53    Address(physical_address_t address)
54        : m_address(address)
55    { }
56
57    Address(const Address& obj);
58    Address& operator=(const Address& obj);
59
60    void setAddress(physical_address_t address) { m_address = address; }
61    physical_address_t getAddress() const {return m_address;}
62    // selects bits inclusive
63    physical_address_t bitSelect(unsigned int small, unsigned int big) const;
64    physical_address_t bitRemove(unsigned int small, unsigned int big) const;
65    physical_address_t maskLowOrderBits(unsigned int number) const;
66    physical_address_t maskHighOrderBits(unsigned int number) const;
67    physical_address_t shiftLowOrderBits(unsigned int number) const;
68
69    physical_address_t getLineAddress() const;
70    physical_address_t getOffset() const;
71    void makeLineAddress();
72    void makeNextStrideAddress(int stride);
73
74    int64 memoryModuleIndex() const;
75
76    void print(std::ostream& out) const;
77    void output(std::ostream& out) const;
78    void input(std::istream& in);
79
80    void
81    setOffset(int offset)
82    {
83        // first, zero out the offset bits
84        makeLineAddress();
85        m_address |= (physical_address_t) offset;
86    }
87
88  private:
89    physical_address_t m_address;
90};
91
92inline Address
93line_address(const Address& addr)
94{
95    Address temp(addr);
96    temp.makeLineAddress();
97    return temp;
98}
99
100inline bool
101operator<(const Address& obj1, const Address& obj2)
102{
103    return obj1.getAddress() < obj2.getAddress();
104}
105
106inline std::ostream&
107operator<<(std::ostream& out, const Address& obj)
108{
109    obj.print(out);
110    out << std::flush;
111    return out;
112}
113
114inline bool
115operator==(const Address& obj1, const Address& obj2)
116{
117    return (obj1.getAddress() == obj2.getAddress());
118}
119
120inline bool
121operator!=(const Address& obj1, const Address& obj2)
122{
123    return (obj1.getAddress() != obj2.getAddress());
124}
125
126// rips bits inclusive
127inline physical_address_t
128Address::bitSelect(unsigned int small, unsigned int big) const
129{
130    physical_address_t mask;
131    assert(big >= small);
132
133    if (big >= ADDRESS_WIDTH - 1) {
134        return (m_address >> small);
135    } else {
136        mask = ~((physical_address_t)~0 << (big + 1));
137        // FIXME - this is slow to manipulate a 64-bit number using 32-bits
138        physical_address_t partial = (m_address & mask);
139        return (partial >> small);
140    }
141}
142
143// removes bits inclusive
144inline physical_address_t
145Address::bitRemove(unsigned int small, unsigned int big) const
146{
147    physical_address_t mask;
148    assert(big >= small);
149
150    if (small >= ADDRESS_WIDTH - 1) {
151        return m_address;
152    } else if (big >= ADDRESS_WIDTH - 1) {
153        mask = (physical_address_t)~0 >> small;
154        return (m_address & mask);
155    } else if (small == 0) {
156        mask = (physical_address_t)~0 << big;
157        return (m_address & mask);
158    } else {
159        mask = ~((physical_address_t)~0 << small);
160        physical_address_t lower_bits = m_address & mask;
161        mask = (physical_address_t)~0 << (big + 1);
162        physical_address_t higher_bits = m_address & mask;
163
164        // Shift the valid high bits over the removed section
165        higher_bits = higher_bits >> (big - small + 1);
166        return (higher_bits | lower_bits);
167    }
168}
169
170inline physical_address_t
171Address::maskLowOrderBits(unsigned int number) const
172{
173  physical_address_t mask;
174
175  if (number >= ADDRESS_WIDTH - 1) {
176      mask = ~0;
177  } else {
178      mask = (physical_address_t)~0 << number;
179  }
180  return (m_address & mask);
181}
182
183inline physical_address_t
184Address::maskHighOrderBits(unsigned int number) const
185{
186    physical_address_t mask;
187
188    if (number >= ADDRESS_WIDTH - 1) {
189        mask = ~0;
190    } else {
191        mask = (physical_address_t)~0 >> number;
192    }
193    return (m_address & mask);
194}
195
196inline physical_address_t
197Address::shiftLowOrderBits(unsigned int number) const
198{
199    return (m_address >> number);
200}
201
202Address next_stride_address(const Address& addr, int stride);
203
204__hash_namespace_begin
205template <> struct hash<Address>
206{
207    size_t
208    operator()(const Address &s) const
209    {
210        return (size_t)s.getAddress();
211    }
212};
213__hash_namespace_end
214
215namespace std {
216template <> struct equal_to<Address>
217{
218    bool
219    operator()(const Address& s1, const Address& s2) const
220    {
221        return s1 == s2;
222    }
223};
224} // namespace std
225
226#endif // __MEM_RUBY_COMMON_ADDRESS_HH__
227