decode_cache.hh revision 12621
1/* 2 * Copyright (c) 2011 Google 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 * Authors: Gabe Black 29 */ 30 31#ifndef __CPU_DECODE_CACHE_HH__ 32#define __CPU_DECODE_CACHE_HH__ 33 34#include <unordered_map> 35 36#include "arch/isa_traits.hh" 37#include "arch/types.hh" 38#include "config/the_isa.hh" 39#include "cpu/static_inst_fwd.hh" 40 41namespace TheISA 42{ 43 class Decoder; 44} 45 46namespace DecodeCache 47{ 48 49/// Hash for decoded instructions. 50template <typename EMI> 51using InstMap = std::unordered_map<EMI, StaticInstPtr>; 52 53/// A sparse map from an Addr to a Value, stored in page chunks. 54template<class Value> 55class AddrMap 56{ 57 protected: 58 // A pages worth of cache entries. 59 struct CachePage { 60 Value items[TheISA::PageBytes]; 61 }; 62 // A map of cache pages which allows a sparse mapping. 63 typedef typename std::unordered_map<Addr, CachePage *> PageMap; 64 typedef typename PageMap::iterator PageIt; 65 // Mini cache of recent lookups. 66 PageIt recent[2]; 67 PageMap pageMap; 68 69 /// Update the mini cache of recent lookups. 70 /// @param recentest The most recent result; 71 void 72 update(PageIt recentest) 73 { 74 recent[1] = recent[0]; 75 recent[0] = recentest; 76 } 77 78 /// Attempt to find the CacheePage which goes with a particular 79 /// address. First check the small cache of recent results, then 80 /// actually look in the hash map. 81 /// @param addr The address to look up. 82 CachePage * 83 getPage(Addr addr) 84 { 85 Addr page_addr = addr & ~(TheISA::PageBytes - 1); 86 87 // Check against recent lookups. 88 if (recent[0] != pageMap.end()) { 89 if (recent[0]->first == page_addr) 90 return recent[0]->second; 91 if (recent[1] != pageMap.end() && 92 recent[1]->first == page_addr) { 93 update(recent[1]); 94 // recent[1] has just become recent[0]. 95 return recent[0]->second; 96 } 97 } 98 99 // Actually look in the has_map. 100 PageIt it = pageMap.find(page_addr); 101 if (it != pageMap.end()) { 102 update(it); 103 return it->second; 104 } 105 106 // Didn't find an existing page, so add a new one. 107 CachePage *newPage = new CachePage; 108 page_addr = page_addr & ~(TheISA::PageBytes - 1); 109 typename PageMap::value_type to_insert(page_addr, newPage); 110 update(pageMap.insert(to_insert).first); 111 return newPage; 112 } 113 114 public: 115 /// Constructor 116 AddrMap() 117 { 118 recent[0] = recent[1] = pageMap.end(); 119 } 120 121 Value & 122 lookup(Addr addr) 123 { 124 CachePage *page = getPage(addr); 125 return page->items[addr & (TheISA::PageBytes - 1)]; 126 } 127}; 128 129} // namespace DecodeCache 130 131#endif // __CPU_DECODE_CACHE_HH__ 132