decode_cache.hh revision 9021
11689SN/A/* 21689SN/A * Copyright (c) 2011 Google 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Gabe Black 292756Sksewell@umich.edu */ 301689SN/A 311689SN/A#ifndef __CPU_DECODE_CACHE_HH__ 322325SN/A#define __CPU_DECODE_CACHE_HH__ 332325SN/A 341060SN/A#include "arch/isa_traits.hh" 351060SN/A#include "arch/types.hh" 361060SN/A#include "base/hashmap.hh" 372292SN/A#include "config/the_isa.hh" 382292SN/A#include "cpu/static_inst.hh" 391681SN/A 401060SN/Atypedef StaticInstPtr (*DecodeInstFunc)(TheISA::ExtMachInst); 412980Sgblack@eecs.umich.edu 421060SN/Atemplate <DecodeInstFunc decodeInstFunc> 431060SN/Aclass DecodeCache 441858SN/A{ 454598Sbinkertn@umich.edu private: 462325SN/A typedef TheISA::ExtMachInst ExtMachInst; 471717SN/A 482683Sktlim@umich.edu /// Hash of decoded instructions. 491717SN/A typedef m5::hash_map<ExtMachInst, StaticInstPtr> InstMap; 501717SN/A InstMap instMap; 512292SN/A struct DecodePage { 522292SN/A StaticInstPtr insts[TheISA::PageBytes]; 532817Sksewell@umich.edu }; 541060SN/A 551060SN/A /// A store of DecodePages. Basically a slightly smarter hash_map. 565529Snate@binkert.org class DecodePages 575529Snate@binkert.org { 582316SN/A protected: 592316SN/A typedef typename m5::hash_map<Addr, DecodePage *> PageMap; 602680Sktlim@umich.edu typedef typename PageMap::iterator PageIt; 612817Sksewell@umich.edu PageIt recent[2]; 622817Sksewell@umich.edu PageMap pageMap; 632843Sktlim@umich.edu 642843Sktlim@umich.edu /// Update the small cache of recent lookups. 652669Sktlim@umich.edu /// @param recentest The most recent result; 661060SN/A void 671060SN/A update(PageIt recentest) 685529Snate@binkert.org { 695529Snate@binkert.org recent[1] = recent[0]; 702733Sktlim@umich.edu recent[0] = recentest; 711060SN/A } 721060SN/A 731060SN/A void 745529Snate@binkert.org addPage(Addr addr, DecodePage *page) 752292SN/A { 762292SN/A Addr page_addr = addr & ~(TheISA::PageBytes - 1); 772632Sstever@eecs.umich.edu typename PageMap::value_type to_insert(page_addr, page); 782817Sksewell@umich.edu update(pageMap.insert(to_insert).first); 792817Sksewell@umich.edu } 802817Sksewell@umich.edu 812817Sksewell@umich.edu public: 822669Sktlim@umich.edu /// Constructor 831681SN/A DecodePages() 841685SN/A { 851681SN/A recent[0] = recent[1] = pageMap.end(); 861060SN/A } 871060SN/A 882348SN/A /// Attempt to find the DecodePage which goes with a particular 892348SN/A /// address. First check the small cache of recent results, then 902348SN/A /// actually look in the hash_map. 912348SN/A /// @param addr The address to look up. 922348SN/A DecodePage * 931060SN/A getPage(Addr addr) 942733Sktlim@umich.edu { 951060SN/A Addr page_addr = addr & ~(TheISA::PageBytes - 1); 961060SN/A 972325SN/A // Check against recent lookups. 981060SN/A if (recent[0] != pageMap.end()) { 991061SN/A if (recent[0]->first == page_addr) 1004329Sktlim@umich.edu return recent[0]->second; 1011060SN/A if (recent[1] != pageMap.end() && 1022292SN/A recent[1]->first == page_addr) { 1032292SN/A update(recent[1]); 1042292SN/A // recent[1] has just become recent[0]. 1052292SN/A return recent[0]->second; 1062817Sksewell@umich.edu } 1072829Sksewell@umich.edu } 1081060SN/A 1091060SN/A // Actually look in the has_map. 1101060SN/A PageIt it = pageMap.find(page_addr); 1111060SN/A if (it != pageMap.end()) { 1121060SN/A update(it); 1132307SN/A return it->second; 1142307SN/A } 1151060SN/A 1161060SN/A // Didn't find an existing page, so add a new one. 1173781Sgblack@eecs.umich.edu DecodePage *newPage = new DecodePage; 1183781Sgblack@eecs.umich.edu addPage(page_addr, newPage); 1193781Sgblack@eecs.umich.edu return newPage; 1202292SN/A } 1211060SN/A } decodePages; 1221060SN/A 1232829Sksewell@umich.edu public: 1242829Sksewell@umich.edu /// Decode a machine instruction. 1252829Sksewell@umich.edu /// @param mach_inst The binary instruction to decode. 1261060SN/A /// @retval A pointer to the corresponding StaticInst object. 1271060SN/A StaticInstPtr 1281060SN/A decode(ExtMachInst mach_inst, Addr addr) 1291060SN/A { 1302292SN/A // Try to find a matching address based table of instructions. 1311755SN/A DecodePage *page = decodePages.getPage(addr); 1321060SN/A 1331060SN/A // Use the table to decode the instruction. It will fall back to other 1342292SN/A // mechanisms if it needs to. 1351755SN/A Addr offset = addr & (TheISA::PageBytes - 1); 1362292SN/A StaticInstPtr si = page->insts[offset]; 1372292SN/A if (si && (si->machInst == mach_inst)) 1381060SN/A return si; 1392292SN/A 1405336Shines@cs.fsu.edu InstMap::iterator iter = instMap.find(mach_inst); 1411060SN/A if (iter != instMap.end()) { 1421060SN/A si = iter->second; 1432292SN/A page->insts[offset] = si; 1441060SN/A return si; 1451060SN/A } 1462292SN/A 1471060SN/A si = decodeInstFunc(mach_inst); 1481060SN/A instMap[mach_inst] = si; 1491060SN/A page->insts[offset] = si; 1505100Ssaidi@eecs.umich.edu return si; 1511060SN/A } 1525100Ssaidi@eecs.umich.edu}; 1531060SN/A 1541060SN/A#endif // __CPU_DECODE_CACHE_HH__ 1552292SN/A