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