18541Sgblack@eecs.umich.edu/* 28541Sgblack@eecs.umich.edu * Copyright (c) 2011 Google 38541Sgblack@eecs.umich.edu * All rights reserved. 48541Sgblack@eecs.umich.edu * 58541Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 68541Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 78541Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 88541Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 98541Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 108541Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 118541Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 128541Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 138541Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 148541Sgblack@eecs.umich.edu * this software without specific prior written permission. 158541Sgblack@eecs.umich.edu * 168541Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178541Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188541Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198541Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 208541Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218541Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228541Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238541Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248541Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258541Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 268541Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278541Sgblack@eecs.umich.edu * 288541Sgblack@eecs.umich.edu * Authors: Gabe Black 298541Sgblack@eecs.umich.edu */ 308541Sgblack@eecs.umich.edu 318541Sgblack@eecs.umich.edu#ifndef __CPU_DECODE_CACHE_HH__ 328541Sgblack@eecs.umich.edu#define __CPU_DECODE_CACHE_HH__ 338541Sgblack@eecs.umich.edu 3411168Sandreas.hansson@arm.com#include <unordered_map> 3511168Sandreas.hansson@arm.com 368541Sgblack@eecs.umich.edu#include "arch/isa_traits.hh" 378541Sgblack@eecs.umich.edu#include "arch/types.hh" 388541Sgblack@eecs.umich.edu#include "config/the_isa.hh" 399024Sgblack@eecs.umich.edu#include "cpu/static_inst_fwd.hh" 408541Sgblack@eecs.umich.edu 419022Sgblack@eecs.umich.edunamespace TheISA 429022Sgblack@eecs.umich.edu{ 439022Sgblack@eecs.umich.edu class Decoder; 449022Sgblack@eecs.umich.edu} 458541Sgblack@eecs.umich.edu 469024Sgblack@eecs.umich.edunamespace DecodeCache 478541Sgblack@eecs.umich.edu{ 488541Sgblack@eecs.umich.edu 499024Sgblack@eecs.umich.edu/// Hash for decoded instructions. 5012621Sgabeblack@google.comtemplate <typename EMI> 5112621Sgabeblack@google.comusing InstMap = std::unordered_map<EMI, StaticInstPtr>; 529024Sgblack@eecs.umich.edu 539024Sgblack@eecs.umich.edu/// A sparse map from an Addr to a Value, stored in page chunks. 549024Sgblack@eecs.umich.edutemplate<class Value> 559024Sgblack@eecs.umich.educlass AddrMap 569024Sgblack@eecs.umich.edu{ 579024Sgblack@eecs.umich.edu protected: 589024Sgblack@eecs.umich.edu // A pages worth of cache entries. 599024Sgblack@eecs.umich.edu struct CachePage { 609024Sgblack@eecs.umich.edu Value items[TheISA::PageBytes]; 618541Sgblack@eecs.umich.edu }; 629024Sgblack@eecs.umich.edu // A map of cache pages which allows a sparse mapping. 6311168Sandreas.hansson@arm.com typedef typename std::unordered_map<Addr, CachePage *> PageMap; 649024Sgblack@eecs.umich.edu typedef typename PageMap::iterator PageIt; 659024Sgblack@eecs.umich.edu // Mini cache of recent lookups. 669024Sgblack@eecs.umich.edu PageIt recent[2]; 679024Sgblack@eecs.umich.edu PageMap pageMap; 688541Sgblack@eecs.umich.edu 699024Sgblack@eecs.umich.edu /// Update the mini cache of recent lookups. 709024Sgblack@eecs.umich.edu /// @param recentest The most recent result; 719024Sgblack@eecs.umich.edu void 729024Sgblack@eecs.umich.edu update(PageIt recentest) 738541Sgblack@eecs.umich.edu { 749024Sgblack@eecs.umich.edu recent[1] = recent[0]; 759024Sgblack@eecs.umich.edu recent[0] = recentest; 769024Sgblack@eecs.umich.edu } 778541Sgblack@eecs.umich.edu 789024Sgblack@eecs.umich.edu /// Attempt to find the CacheePage which goes with a particular 799024Sgblack@eecs.umich.edu /// address. First check the small cache of recent results, then 8011168Sandreas.hansson@arm.com /// actually look in the hash map. 819024Sgblack@eecs.umich.edu /// @param addr The address to look up. 829024Sgblack@eecs.umich.edu CachePage * 839024Sgblack@eecs.umich.edu getPage(Addr addr) 849024Sgblack@eecs.umich.edu { 859024Sgblack@eecs.umich.edu Addr page_addr = addr & ~(TheISA::PageBytes - 1); 869021Sgblack@eecs.umich.edu 879024Sgblack@eecs.umich.edu // Check against recent lookups. 889024Sgblack@eecs.umich.edu if (recent[0] != pageMap.end()) { 899024Sgblack@eecs.umich.edu if (recent[0]->first == page_addr) 909024Sgblack@eecs.umich.edu return recent[0]->second; 919024Sgblack@eecs.umich.edu if (recent[1] != pageMap.end() && 929024Sgblack@eecs.umich.edu recent[1]->first == page_addr) { 939024Sgblack@eecs.umich.edu update(recent[1]); 949024Sgblack@eecs.umich.edu // recent[1] has just become recent[0]. 959024Sgblack@eecs.umich.edu return recent[0]->second; 969024Sgblack@eecs.umich.edu } 979024Sgblack@eecs.umich.edu } 988541Sgblack@eecs.umich.edu 999024Sgblack@eecs.umich.edu // Actually look in the has_map. 1009024Sgblack@eecs.umich.edu PageIt it = pageMap.find(page_addr); 1019024Sgblack@eecs.umich.edu if (it != pageMap.end()) { 1029024Sgblack@eecs.umich.edu update(it); 1039024Sgblack@eecs.umich.edu return it->second; 1049024Sgblack@eecs.umich.edu } 1059024Sgblack@eecs.umich.edu 1069024Sgblack@eecs.umich.edu // Didn't find an existing page, so add a new one. 1079024Sgblack@eecs.umich.edu CachePage *newPage = new CachePage; 1089024Sgblack@eecs.umich.edu page_addr = page_addr & ~(TheISA::PageBytes - 1); 1099024Sgblack@eecs.umich.edu typename PageMap::value_type to_insert(page_addr, newPage); 1109024Sgblack@eecs.umich.edu update(pageMap.insert(to_insert).first); 1119024Sgblack@eecs.umich.edu return newPage; 1129024Sgblack@eecs.umich.edu } 1138541Sgblack@eecs.umich.edu 1148541Sgblack@eecs.umich.edu public: 1159024Sgblack@eecs.umich.edu /// Constructor 1169024Sgblack@eecs.umich.edu AddrMap() 1179024Sgblack@eecs.umich.edu { 1189024Sgblack@eecs.umich.edu recent[0] = recent[1] = pageMap.end(); 1199024Sgblack@eecs.umich.edu } 1209024Sgblack@eecs.umich.edu 1219024Sgblack@eecs.umich.edu Value & 1229024Sgblack@eecs.umich.edu lookup(Addr addr) 1239024Sgblack@eecs.umich.edu { 1249024Sgblack@eecs.umich.edu CachePage *page = getPage(addr); 1259024Sgblack@eecs.umich.edu return page->items[addr & (TheISA::PageBytes - 1)]; 1269024Sgblack@eecs.umich.edu } 1278541Sgblack@eecs.umich.edu}; 1288541Sgblack@eecs.umich.edu 1299024Sgblack@eecs.umich.edu} // namespace DecodeCache 1309024Sgblack@eecs.umich.edu 1318541Sgblack@eecs.umich.edu#endif // __CPU_DECODE_CACHE_HH__ 132