decode_cache.hh revision 12621
12735Sktlim@umich.edu/*
210319SAndreas.Sandberg@ARM.com * Copyright (c) 2011 Google
310319SAndreas.Sandberg@ARM.com * All rights reserved.
410319SAndreas.Sandberg@ARM.com *
510319SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
610319SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
710319SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
810319SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
910319SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
1010319SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
1110319SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
1210319SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
1310319SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from
142735Sktlim@umich.edu * this software without specific prior written permission.
1511303Ssteve.reinhardt@amd.com *
162735Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172735Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182735Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192735Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202735Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212735Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222735Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232735Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242735Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252735Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262735Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272735Sktlim@umich.edu *
282735Sktlim@umich.edu * Authors: Gabe Black
292735Sktlim@umich.edu */
302735Sktlim@umich.edu
312735Sktlim@umich.edu#ifndef __CPU_DECODE_CACHE_HH__
322735Sktlim@umich.edu#define __CPU_DECODE_CACHE_HH__
332735Sktlim@umich.edu
342735Sktlim@umich.edu#include <unordered_map>
352735Sktlim@umich.edu
362735Sktlim@umich.edu#include "arch/isa_traits.hh"
372735Sktlim@umich.edu#include "arch/types.hh"
382735Sktlim@umich.edu#include "config/the_isa.hh"
392735Sktlim@umich.edu#include "cpu/static_inst_fwd.hh"
402735Sktlim@umich.edu
412735Sktlim@umich.edunamespace TheISA
4210319SAndreas.Sandberg@ARM.com{
432735Sktlim@umich.edu    class Decoder;
442735Sktlim@umich.edu}
4510319SAndreas.Sandberg@ARM.com
4610319SAndreas.Sandberg@ARM.comnamespace DecodeCache
4710319SAndreas.Sandberg@ARM.com{
4810319SAndreas.Sandberg@ARM.com
4910319SAndreas.Sandberg@ARM.com/// Hash for decoded instructions.
5010319SAndreas.Sandberg@ARM.comtemplate <typename EMI>
5110529Smorr@cs.wisc.eduusing InstMap = std::unordered_map<EMI, StaticInstPtr>;
5210319SAndreas.Sandberg@ARM.com
5310319SAndreas.Sandberg@ARM.com/// A sparse map from an Addr to a Value, stored in page chunks.
5411608Snikos.nikoleris@arm.comtemplate<class Value>
552735Sktlim@umich.educlass AddrMap
562735Sktlim@umich.edu{
5710319SAndreas.Sandberg@ARM.com  protected:
5810319SAndreas.Sandberg@ARM.com    // A pages worth of cache entries.
5910319SAndreas.Sandberg@ARM.com    struct CachePage {
6010319SAndreas.Sandberg@ARM.com        Value items[TheISA::PageBytes];
6110319SAndreas.Sandberg@ARM.com    };
6210319SAndreas.Sandberg@ARM.com    // A map of cache pages which allows a sparse mapping.
6310319SAndreas.Sandberg@ARM.com    typedef typename std::unordered_map<Addr, CachePage *> PageMap;
6410319SAndreas.Sandberg@ARM.com    typedef typename PageMap::iterator PageIt;
6510319SAndreas.Sandberg@ARM.com    // Mini cache of recent lookups.
6610319SAndreas.Sandberg@ARM.com    PageIt recent[2];
6710319SAndreas.Sandberg@ARM.com    PageMap pageMap;
6810319SAndreas.Sandberg@ARM.com
6910319SAndreas.Sandberg@ARM.com    /// Update the mini cache of recent lookups.
7010319SAndreas.Sandberg@ARM.com    /// @param recentest The most recent result;
712735Sktlim@umich.edu    void
722735Sktlim@umich.edu    update(PageIt recentest)
7310319SAndreas.Sandberg@ARM.com    {
7410319SAndreas.Sandberg@ARM.com        recent[1] = recent[0];
7510319SAndreas.Sandberg@ARM.com        recent[0] = recentest;
7610319SAndreas.Sandberg@ARM.com    }
7710319SAndreas.Sandberg@ARM.com
7810319SAndreas.Sandberg@ARM.com    /// Attempt to find the CacheePage which goes with a particular
7910319SAndreas.Sandberg@ARM.com    /// address. First check the small cache of recent results, then
8010319SAndreas.Sandberg@ARM.com    /// actually look in the hash map.
8110319SAndreas.Sandberg@ARM.com    /// @param addr The address to look up.
8210319SAndreas.Sandberg@ARM.com    CachePage *
8310319SAndreas.Sandberg@ARM.com    getPage(Addr addr)
8410319SAndreas.Sandberg@ARM.com    {
8510319SAndreas.Sandberg@ARM.com        Addr page_addr = addr & ~(TheISA::PageBytes - 1);
8610319SAndreas.Sandberg@ARM.com
8710319SAndreas.Sandberg@ARM.com        // Check against recent lookups.
882735Sktlim@umich.edu        if (recent[0] != pageMap.end()) {
892735Sktlim@umich.edu            if (recent[0]->first == page_addr)
9010319SAndreas.Sandberg@ARM.com                return recent[0]->second;
9110319SAndreas.Sandberg@ARM.com            if (recent[1] != pageMap.end() &&
9210319SAndreas.Sandberg@ARM.com                    recent[1]->first == page_addr) {
9310319SAndreas.Sandberg@ARM.com                update(recent[1]);
9410319SAndreas.Sandberg@ARM.com                // recent[1] has just become recent[0].
9510319SAndreas.Sandberg@ARM.com                return recent[0]->second;
9610319SAndreas.Sandberg@ARM.com            }
9710319SAndreas.Sandberg@ARM.com        }
9810319SAndreas.Sandberg@ARM.com
9910319SAndreas.Sandberg@ARM.com        // Actually look in the has_map.
10010319SAndreas.Sandberg@ARM.com        PageIt it = pageMap.find(page_addr);
10110319SAndreas.Sandberg@ARM.com        if (it != pageMap.end()) {
10210319SAndreas.Sandberg@ARM.com            update(it);
1032735Sktlim@umich.edu            return it->second;
1042735Sktlim@umich.edu        }
10510319SAndreas.Sandberg@ARM.com
1062735Sktlim@umich.edu        // Didn't find an existing page, so add a new one.
1072735Sktlim@umich.edu        CachePage *newPage = new CachePage;
1082735Sktlim@umich.edu        page_addr = page_addr & ~(TheISA::PageBytes - 1);
10910319SAndreas.Sandberg@ARM.com        typename PageMap::value_type to_insert(page_addr, newPage);
11010319SAndreas.Sandberg@ARM.com        update(pageMap.insert(to_insert).first);
1112735Sktlim@umich.edu        return newPage;
1122735Sktlim@umich.edu    }
11310319SAndreas.Sandberg@ARM.com
11410319SAndreas.Sandberg@ARM.com  public:
1152735Sktlim@umich.edu    /// Constructor
1162735Sktlim@umich.edu    AddrMap()
1172735Sktlim@umich.edu    {
11810319SAndreas.Sandberg@ARM.com        recent[0] = recent[1] = pageMap.end();
11910319SAndreas.Sandberg@ARM.com    }
1202735Sktlim@umich.edu
12110319SAndreas.Sandberg@ARM.com    Value &
1222735Sktlim@umich.edu    lookup(Addr addr)
12310319SAndreas.Sandberg@ARM.com    {
12410319SAndreas.Sandberg@ARM.com        CachePage *page = getPage(addr);
12510319SAndreas.Sandberg@ARM.com        return page->items[addr & (TheISA::PageBytes - 1)];
12610319SAndreas.Sandberg@ARM.com    }
12710319SAndreas.Sandberg@ARM.com};
12810319SAndreas.Sandberg@ARM.com
12910319SAndreas.Sandberg@ARM.com} // namespace DecodeCache
1302735Sktlim@umich.edu
13110319SAndreas.Sandberg@ARM.com#endif // __CPU_DECODE_CACHE_HH__
13210319SAndreas.Sandberg@ARM.com