Address.hh revision 8485:7a9a7f2a3d46
17584SN/A/*
28869SAli.Saidi@ARM.com * Copyright (c) 1999 Mark D. Hill and David A. Wood
37584SN/A * All rights reserved.
47584SN/A *
57584SN/A * Redistribution and use in source and binary forms, with or without
67584SN/A * modification, are permitted provided that the following conditions are
77584SN/A * met: redistributions of source code must retain the above copyright
87584SN/A * notice, this list of conditions and the following disclaimer;
97584SN/A * redistributions in binary form must reproduce the above copyright
107584SN/A * notice, this list of conditions and the following disclaimer in the
117584SN/A * documentation and/or other materials provided with the distribution;
127584SN/A * neither the name of the copyright holders nor the names of its
137584SN/A * contributors may be used to endorse or promote products derived from
147584SN/A * this software without specific prior written permission.
157584SN/A *
167584SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177584SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187584SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197584SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207584SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217584SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227584SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237584SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247584SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257584SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267584SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277584SN/A */
287584SN/A
297584SN/A#ifndef __MEM_RUBY_COMMON_ADDRESS_HH__
307584SN/A#define __MEM_RUBY_COMMON_ADDRESS_HH__
317584SN/A
327584SN/A#include <cassert>
337584SN/A#include <iomanip>
347584SN/A
357584SN/A#include "base/hashmap.hh"
367584SN/A#include "mem/ruby/common/Global.hh"
377584SN/A#include "mem/ruby/system/NodeID.hh"
387584SN/A
397584SN/Aconst int ADDRESS_WIDTH = 64; // address width in bytes
407584SN/A
418869SAli.Saidi@ARM.comclass Address;
427584SN/Atypedef Address PhysAddress;
438245SN/Atypedef Address VirtAddress;
448245SN/A
458869SAli.Saidi@ARM.comclass Address
468869SAli.Saidi@ARM.com{
478869SAli.Saidi@ARM.com  public:
487584SN/A    Address()
497584SN/A        : m_address(0)
507584SN/A    { }
517587SN/A
527587SN/A    explicit
538869SAli.Saidi@ARM.com    Address(physical_address_t address)
548869SAli.Saidi@ARM.com        : m_address(address)
558904SAli.Saidi@ARM.com    { }
568904SAli.Saidi@ARM.com
577584SN/A    Address(const Address& obj);
587584SN/A    Address& operator=(const Address& obj);
597584SN/A
607584SN/A    void setAddress(physical_address_t address) { m_address = address; }
617584SN/A    physical_address_t getAddress() const {return m_address;}
627584SN/A    // selects bits inclusive
638869SAli.Saidi@ARM.com    physical_address_t bitSelect(int small, int big) const;
647584SN/A    physical_address_t bitRemove(int small, int big) const;
657584SN/A    physical_address_t maskLowOrderBits(int number) const;
667584SN/A    physical_address_t maskHighOrderBits(int number) const;
677584SN/A    physical_address_t shiftLowOrderBits(int number) const;
687584SN/A
698869SAli.Saidi@ARM.com    physical_address_t getLineAddress() const;
707584SN/A    physical_address_t getOffset() const;
718869SAli.Saidi@ARM.com    void makeLineAddress();
728869SAli.Saidi@ARM.com    void makeNextStrideAddress(int stride);
738869SAli.Saidi@ARM.com
748869SAli.Saidi@ARM.com    int getBankSetNum() const;
758869SAli.Saidi@ARM.com    int getBankSetDist() const;
768869SAli.Saidi@ARM.com
778869SAli.Saidi@ARM.com    Index memoryModuleIndex() const;
788869SAli.Saidi@ARM.com
798869SAli.Saidi@ARM.com    void print(std::ostream& out) const;
808869SAli.Saidi@ARM.com    void output(std::ostream& out) const;
818869SAli.Saidi@ARM.com    void input(std::istream& in);
828869SAli.Saidi@ARM.com
838869SAli.Saidi@ARM.com    void
848869SAli.Saidi@ARM.com    setOffset(int offset)
858869SAli.Saidi@ARM.com    {
868869SAli.Saidi@ARM.com        // first, zero out the offset bits
878869SAli.Saidi@ARM.com        makeLineAddress();
888869SAli.Saidi@ARM.com        m_address |= (physical_address_t) offset;
898869SAli.Saidi@ARM.com    }
908869SAli.Saidi@ARM.com
918869SAli.Saidi@ARM.com  private:
928869SAli.Saidi@ARM.com    physical_address_t m_address;
938869SAli.Saidi@ARM.com};
948869SAli.Saidi@ARM.com
958869SAli.Saidi@ARM.cominline Address
968869SAli.Saidi@ARM.comline_address(const Address& addr)
978869SAli.Saidi@ARM.com{
988869SAli.Saidi@ARM.com    Address temp(addr);
998869SAli.Saidi@ARM.com    temp.makeLineAddress();
1008869SAli.Saidi@ARM.com    return temp;
1018869SAli.Saidi@ARM.com}
1028869SAli.Saidi@ARM.com
1038869SAli.Saidi@ARM.cominline bool
1048869SAli.Saidi@ARM.comoperator<(const Address& obj1, const Address& obj2)
1058869SAli.Saidi@ARM.com{
1068869SAli.Saidi@ARM.com    return obj1.getAddress() < obj2.getAddress();
1078869SAli.Saidi@ARM.com}
1088869SAli.Saidi@ARM.com
1098869SAli.Saidi@ARM.cominline std::ostream&
1108869SAli.Saidi@ARM.comoperator<<(std::ostream& out, const Address& obj)
1118869SAli.Saidi@ARM.com{
1128869SAli.Saidi@ARM.com    obj.print(out);
1138869SAli.Saidi@ARM.com    out << std::flush;
1148869SAli.Saidi@ARM.com    return out;
1158869SAli.Saidi@ARM.com}
1168869SAli.Saidi@ARM.com
1178869SAli.Saidi@ARM.cominline bool
1188869SAli.Saidi@ARM.comoperator==(const Address& obj1, const Address& obj2)
1198869SAli.Saidi@ARM.com{
1208869SAli.Saidi@ARM.com    return (obj1.getAddress() == obj2.getAddress());
1217584SN/A}
1227584SN/A
1237584SN/Ainline bool
1247584SN/Aoperator!=(const Address& obj1, const Address& obj2)
1257584SN/A{
1268869SAli.Saidi@ARM.com    return (obj1.getAddress() != obj2.getAddress());
1277584SN/A}
1287584SN/A
1297584SN/A// rips bits inclusive
1307584SN/Ainline physical_address_t
1317584SN/AAddress::bitSelect(int small, int big) const
1328869SAli.Saidi@ARM.com{
1337584SN/A    physical_address_t mask;
1348869SAli.Saidi@ARM.com    assert((unsigned)big >= (unsigned)small);
1358869SAli.Saidi@ARM.com
1368869SAli.Saidi@ARM.com    if (big >= ADDRESS_WIDTH - 1) {
1378869SAli.Saidi@ARM.com        return (m_address >> small);
1388869SAli.Saidi@ARM.com    } else {
1398869SAli.Saidi@ARM.com        mask = ~((physical_address_t)~0 << (big + 1));
1408869SAli.Saidi@ARM.com        // FIXME - this is slow to manipulate a 64-bit number using 32-bits
1418869SAli.Saidi@ARM.com        physical_address_t partial = (m_address & mask);
1428869SAli.Saidi@ARM.com        return (partial >> small);
1438869SAli.Saidi@ARM.com    }
1448869SAli.Saidi@ARM.com}
1458869SAli.Saidi@ARM.com
1468869SAli.Saidi@ARM.com// removes bits inclusive
1478869SAli.Saidi@ARM.cominline physical_address_t
1488869SAli.Saidi@ARM.comAddress::bitRemove(int small, int big) const
1498869SAli.Saidi@ARM.com{
1508869SAli.Saidi@ARM.com    physical_address_t mask;
1518869SAli.Saidi@ARM.com    assert((unsigned)big >= (unsigned)small);
1528869SAli.Saidi@ARM.com
1538869SAli.Saidi@ARM.com    if (small >= ADDRESS_WIDTH - 1) {
1548869SAli.Saidi@ARM.com        return m_address;
1558869SAli.Saidi@ARM.com    } else if (big >= ADDRESS_WIDTH - 1) {
1568869SAli.Saidi@ARM.com        mask = (physical_address_t)~0 >> small;
1578869SAli.Saidi@ARM.com        return (m_address & mask);
1588869SAli.Saidi@ARM.com    } else if (small == 0) {
1598869SAli.Saidi@ARM.com        mask = (physical_address_t)~0 << big;
1608869SAli.Saidi@ARM.com        return (m_address & mask);
1618869SAli.Saidi@ARM.com    } else {
1628869SAli.Saidi@ARM.com        mask = ~((physical_address_t)~0 << small);
1638869SAli.Saidi@ARM.com        physical_address_t lower_bits = m_address & mask;
1648869SAli.Saidi@ARM.com        mask = (physical_address_t)~0 << (big + 1);
1657584SN/A        physical_address_t higher_bits = m_address & mask;
1667584SN/A
1677584SN/A        // Shift the valid high bits over the removed section
1687584SN/A        higher_bits = higher_bits >> (big - small + 1);
1697584SN/A        return (higher_bits | lower_bits);
1708869SAli.Saidi@ARM.com    }
1717584SN/A}
1728869SAli.Saidi@ARM.com
1738869SAli.Saidi@ARM.cominline physical_address_t
1748869SAli.Saidi@ARM.comAddress::maskLowOrderBits(int number) const
1758869SAli.Saidi@ARM.com{
1768869SAli.Saidi@ARM.com  physical_address_t mask;
1778869SAli.Saidi@ARM.com
1788869SAli.Saidi@ARM.com  if (number >= ADDRESS_WIDTH - 1) {
1798869SAli.Saidi@ARM.com      mask = ~0;
1808869SAli.Saidi@ARM.com  } else {
1818869SAli.Saidi@ARM.com      mask = (physical_address_t)~0 << number;
1828869SAli.Saidi@ARM.com  }
1838869SAli.Saidi@ARM.com  return (m_address & mask);
1848869SAli.Saidi@ARM.com}
1858869SAli.Saidi@ARM.com
1868869SAli.Saidi@ARM.cominline physical_address_t
1878869SAli.Saidi@ARM.comAddress::maskHighOrderBits(int number) const
1888869SAli.Saidi@ARM.com{
1898869SAli.Saidi@ARM.com    physical_address_t mask;
1908869SAli.Saidi@ARM.com
1918869SAli.Saidi@ARM.com    if (number >= ADDRESS_WIDTH - 1) {
1928869SAli.Saidi@ARM.com        mask = ~0;
1938869SAli.Saidi@ARM.com    } else {
1948993SAli.Saidi@ARM.com        mask = (physical_address_t)~0 >> number;
1958869SAli.Saidi@ARM.com    }
1968869SAli.Saidi@ARM.com    return (m_address & mask);
1977584SN/A}
1987584SN/A
1997584SN/Ainline physical_address_t
2007584SN/AAddress::shiftLowOrderBits(int number) const
2018869SAli.Saidi@ARM.com{
2027584SN/A    return (m_address >> number);
2038869SAli.Saidi@ARM.com}
2048869SAli.Saidi@ARM.com
2058869SAli.Saidi@ARM.comclass Address;
2068869SAli.Saidi@ARM.comnamespace __hash_namespace {
2078869SAli.Saidi@ARM.comtemplate <> struct hash<Address>
2088869SAli.Saidi@ARM.com{
2098869SAli.Saidi@ARM.com    size_t
2108869SAli.Saidi@ARM.com    operator()(const Address &s) const
2117584SN/A    {
2128869SAli.Saidi@ARM.com        return (size_t)s.getAddress();
2137733SN/A    }
2147733SN/A};
2157733SN/A} // namespace __hash_namespace
2167733SN/A
2178869SAli.Saidi@ARM.comnamespace std {
2187733SN/Atemplate <> struct equal_to<Address>
2197733SN/A{
2207733SN/A    bool
2217733SN/A    operator()(const Address& s1, const Address& s2) const
2227733SN/A    {
2238869SAli.Saidi@ARM.com        return s1 == s2;
2247733SN/A    }
2258869SAli.Saidi@ARM.com};
2267733SN/A} // namespace std
2278869SAli.Saidi@ARM.com
2288869SAli.Saidi@ARM.com#endif // __MEM_RUBY_COMMON_ADDRESS_HH__
2298869SAli.Saidi@ARM.com