priv.isa revision 3599
12632Sstever@eecs.umich.edu// Copyright (c) 2006 The Regents of The University of Michigan 22632Sstever@eecs.umich.edu// All rights reserved. 32632Sstever@eecs.umich.edu// 42632Sstever@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 52632Sstever@eecs.umich.edu// modification, are permitted provided that the following conditions are 62632Sstever@eecs.umich.edu// met: redistributions of source code must retain the above copyright 72632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 82632Sstever@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 92632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 102632Sstever@eecs.umich.edu// documentation and/or other materials provided with the distribution; 112632Sstever@eecs.umich.edu// neither the name of the copyright holders nor the names of its 122632Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from 132632Sstever@eecs.umich.edu// this software without specific prior written permission. 142632Sstever@eecs.umich.edu// 152632Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162632Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172632Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182632Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192632Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202632Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212632Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222632Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232632Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242632Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252632Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262632Sstever@eecs.umich.edu// 272632Sstever@eecs.umich.edu// Authors: Ali Saidi 282632Sstever@eecs.umich.edu// Gabe Black 292632Sstever@eecs.umich.edu// Steve Reinhardt 302632Sstever@eecs.umich.edu 312469SN/A//////////////////////////////////////////////////////////////////// 322469SN/A// 332482SN/A// Privilege mode instructions 342469SN/A// 352469SN/A 362469SN/Aoutput header {{ 372469SN/A /** 382469SN/A * Base class for privelege mode operations. 392469SN/A */ 402469SN/A class Priv : public SparcStaticInst 412469SN/A { 422469SN/A protected: 432469SN/A // Constructor 442469SN/A Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 452469SN/A SparcStaticInst(mnem, _machInst, __opClass) 462469SN/A { 472469SN/A } 482469SN/A 492469SN/A std::string generateDisassembly(Addr pc, 502469SN/A const SymbolTable *symtab) const; 512469SN/A }; 522469SN/A 533599Sgblack@eecs.umich.edu //This class is for instructions that explicitly read control 543599Sgblack@eecs.umich.edu //registers. It provides a special generateDisassembly function. 553599Sgblack@eecs.umich.edu class RdPriv : public Priv 563599Sgblack@eecs.umich.edu { 573599Sgblack@eecs.umich.edu protected: 583599Sgblack@eecs.umich.edu //Constructor 593599Sgblack@eecs.umich.edu RdPriv(const char *mnem, ExtMachInst _machInst, 603599Sgblack@eecs.umich.edu OpClass __opClass, char const * _regName) : 613599Sgblack@eecs.umich.edu Priv(mnem, _machInst, __opClass), regName(_regName) 623599Sgblack@eecs.umich.edu { 633599Sgblack@eecs.umich.edu } 643599Sgblack@eecs.umich.edu 653599Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, 663599Sgblack@eecs.umich.edu const SymbolTable *symtab) const; 673599Sgblack@eecs.umich.edu 683599Sgblack@eecs.umich.edu char const * regName; 693599Sgblack@eecs.umich.edu }; 703599Sgblack@eecs.umich.edu 713599Sgblack@eecs.umich.edu //This class is for instructions that explicitly write control 723599Sgblack@eecs.umich.edu //registers. It provides a special generateDisassembly function. 733599Sgblack@eecs.umich.edu class WrPriv : public Priv 743599Sgblack@eecs.umich.edu { 753599Sgblack@eecs.umich.edu protected: 763599Sgblack@eecs.umich.edu //Constructor 773599Sgblack@eecs.umich.edu WrPriv(const char *mnem, ExtMachInst _machInst, 783599Sgblack@eecs.umich.edu OpClass __opClass, char const * _regName) : 793599Sgblack@eecs.umich.edu Priv(mnem, _machInst, __opClass), regName(_regName) 803599Sgblack@eecs.umich.edu { 813599Sgblack@eecs.umich.edu } 823599Sgblack@eecs.umich.edu 833599Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, 843599Sgblack@eecs.umich.edu const SymbolTable *symtab) const; 853599Sgblack@eecs.umich.edu 863599Sgblack@eecs.umich.edu char const * regName; 873599Sgblack@eecs.umich.edu }; 883599Sgblack@eecs.umich.edu 892469SN/A /** 902469SN/A * Base class for privelege mode operations with immediates. 912469SN/A */ 922469SN/A class PrivImm : public Priv 932469SN/A { 942469SN/A protected: 952469SN/A // Constructor 962469SN/A PrivImm(const char *mnem, ExtMachInst _machInst, 972469SN/A OpClass __opClass) : 982469SN/A Priv(mnem, _machInst, __opClass), imm(SIMM13) 992469SN/A { 1002469SN/A } 1012469SN/A 1022526SN/A int32_t imm; 1032469SN/A }; 1042469SN/A 1053599Sgblack@eecs.umich.edu //This class is for instructions that explicitly write control 1063599Sgblack@eecs.umich.edu //registers. It provides a special generateDisassembly function. 1073599Sgblack@eecs.umich.edu class WrPrivImm : public PrivImm 1083599Sgblack@eecs.umich.edu { 1093599Sgblack@eecs.umich.edu protected: 1103599Sgblack@eecs.umich.edu //Constructor 1113599Sgblack@eecs.umich.edu WrPrivImm(const char *mnem, ExtMachInst _machInst, 1123599Sgblack@eecs.umich.edu OpClass __opClass, char const * _regName) : 1133599Sgblack@eecs.umich.edu PrivImm(mnem, _machInst, __opClass), regName(_regName) 1143599Sgblack@eecs.umich.edu { 1153599Sgblack@eecs.umich.edu } 1163599Sgblack@eecs.umich.edu 1173599Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, 1183599Sgblack@eecs.umich.edu const SymbolTable *symtab) const; 1193599Sgblack@eecs.umich.edu 1203599Sgblack@eecs.umich.edu char const * regName; 1213599Sgblack@eecs.umich.edu }; 1222469SN/A}}; 1232469SN/A 1242469SN/Aoutput decoder {{ 1252469SN/A std::string Priv::generateDisassembly(Addr pc, 1262469SN/A const SymbolTable *symtab) const 1272469SN/A { 1282944Sgblack@eecs.umich.edu std::stringstream response; 1292944Sgblack@eecs.umich.edu 1302944Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 1312944Sgblack@eecs.umich.edu 1322944Sgblack@eecs.umich.edu return response.str(); 1332469SN/A } 1343599Sgblack@eecs.umich.edu 1353599Sgblack@eecs.umich.edu std::string RdPriv::generateDisassembly(Addr pc, 1363599Sgblack@eecs.umich.edu const SymbolTable *symtab) const 1373599Sgblack@eecs.umich.edu { 1383599Sgblack@eecs.umich.edu std::stringstream response; 1393599Sgblack@eecs.umich.edu 1403599Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 1413599Sgblack@eecs.umich.edu 1423599Sgblack@eecs.umich.edu ccprintf(response, " %%%s, ", regName); 1433599Sgblack@eecs.umich.edu printDestReg(response, 0); 1443599Sgblack@eecs.umich.edu 1453599Sgblack@eecs.umich.edu return response.str(); 1463599Sgblack@eecs.umich.edu } 1473599Sgblack@eecs.umich.edu 1483599Sgblack@eecs.umich.edu std::string WrPriv::generateDisassembly(Addr pc, 1493599Sgblack@eecs.umich.edu const SymbolTable *symtab) const 1503599Sgblack@eecs.umich.edu { 1513599Sgblack@eecs.umich.edu std::stringstream response; 1523599Sgblack@eecs.umich.edu 1533599Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 1543599Sgblack@eecs.umich.edu 1553599Sgblack@eecs.umich.edu ccprintf(response, " "); 1563599Sgblack@eecs.umich.edu printSrcReg(response, 0); 1573599Sgblack@eecs.umich.edu ccprintf(response, ", "); 1583599Sgblack@eecs.umich.edu printSrcReg(response, 1); 1593599Sgblack@eecs.umich.edu ccprintf(response, ", %%%s", regName); 1603599Sgblack@eecs.umich.edu 1613599Sgblack@eecs.umich.edu return response.str(); 1623599Sgblack@eecs.umich.edu } 1633599Sgblack@eecs.umich.edu 1643599Sgblack@eecs.umich.edu std::string WrPrivImm::generateDisassembly(Addr pc, 1653599Sgblack@eecs.umich.edu const SymbolTable *symtab) const 1663599Sgblack@eecs.umich.edu { 1673599Sgblack@eecs.umich.edu std::stringstream response; 1683599Sgblack@eecs.umich.edu 1693599Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 1703599Sgblack@eecs.umich.edu 1713599Sgblack@eecs.umich.edu ccprintf(response, " "); 1723599Sgblack@eecs.umich.edu printSrcReg(response, 0); 1733599Sgblack@eecs.umich.edu ccprintf(response, ", 0x%x, %%%s", imm, regName); 1743599Sgblack@eecs.umich.edu 1753599Sgblack@eecs.umich.edu return response.str(); 1763599Sgblack@eecs.umich.edu } 1773599Sgblack@eecs.umich.edu}}; 1783599Sgblack@eecs.umich.edu 1793599Sgblack@eecs.umich.edudef template ControlRegConstructor {{ 1803599Sgblack@eecs.umich.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 1813599Sgblack@eecs.umich.edu : %(base_class)s("%(mnemonic)s", machInst, 1823599Sgblack@eecs.umich.edu %(op_class)s, "%(reg_name)s") 1833599Sgblack@eecs.umich.edu { 1843599Sgblack@eecs.umich.edu %(constructor)s; 1853599Sgblack@eecs.umich.edu } 1862469SN/A}}; 1872469SN/A 1882469SN/Adef template PrivExecute {{ 1892469SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1902469SN/A Trace::InstRecord *traceData) const 1912469SN/A { 1922469SN/A %(op_decl)s; 1932469SN/A %(op_rd)s; 1942469SN/A 1952469SN/A //If the processor isn't in privileged mode, fault out right away 1962526SN/A if(%(check)s) 1972488SN/A return new PrivilegedAction; 1982469SN/A 1992938Sgblack@eecs.umich.edu Fault fault = NoFault; 2002469SN/A %(code)s; 2012469SN/A %(op_wb)s; 2022938Sgblack@eecs.umich.edu return fault; 2032469SN/A } 2042469SN/A}}; 2052469SN/A 2062526SN/Alet {{ 2072526SN/A def doPrivFormat(code, checkCode, name, Name, opt_flags): 2082526SN/A (usesImm, code, immCode, 2092526SN/A rString, iString) = splitOutImm(code) 2103599Sgblack@eecs.umich.edu #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions, 2113599Sgblack@eecs.umich.edu #cut any other info out of the mnemonic. Also pick a different 2123599Sgblack@eecs.umich.edu #base class. 2133599Sgblack@eecs.umich.edu regBase = 'Priv' 2143599Sgblack@eecs.umich.edu regName = '' 2153599Sgblack@eecs.umich.edu for mnem in ["rdhpr", "rdpr", "rd"]: 2163599Sgblack@eecs.umich.edu if name.startswith(mnem): 2173599Sgblack@eecs.umich.edu regName = name[len(mnem):] 2183599Sgblack@eecs.umich.edu name = mnem 2193599Sgblack@eecs.umich.edu regBase = 'RdPriv' 2203599Sgblack@eecs.umich.edu break 2213599Sgblack@eecs.umich.edu for mnem in ["wrhpr", "wrpr", "wr"]: 2223599Sgblack@eecs.umich.edu if name.startswith(mnem): 2233599Sgblack@eecs.umich.edu regName = name[len(mnem):] 2243599Sgblack@eecs.umich.edu name = mnem 2253599Sgblack@eecs.umich.edu regBase = 'WrPriv' 2263599Sgblack@eecs.umich.edu break 2273599Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, regBase, code, 2283599Sgblack@eecs.umich.edu opt_flags, {"check": checkCode, "reg_name": regName}) 2292469SN/A header_output = BasicDeclare.subst(iop) 2303599Sgblack@eecs.umich.edu if regName == '': 2313599Sgblack@eecs.umich.edu decoder_output = BasicConstructor.subst(iop) 2323599Sgblack@eecs.umich.edu else: 2333599Sgblack@eecs.umich.edu decoder_output = ControlRegConstructor.subst(iop) 2342469SN/A exec_output = PrivExecute.subst(iop) 2352526SN/A if usesImm: 2363599Sgblack@eecs.umich.edu imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', 2373599Sgblack@eecs.umich.edu immCode, opt_flags, {"check": checkCode, "reg_name": regName}) 2382469SN/A header_output += BasicDeclare.subst(imm_iop) 2393599Sgblack@eecs.umich.edu if regName == '': 2403599Sgblack@eecs.umich.edu decoder_output += BasicConstructor.subst(imm_iop) 2413599Sgblack@eecs.umich.edu else: 2423599Sgblack@eecs.umich.edu decoder_output += ControlRegConstructor.subst(imm_iop) 2432469SN/A exec_output += PrivExecute.subst(imm_iop) 2442482SN/A decode_block = ROrImmDecode.subst(iop) 2452469SN/A else: 2462469SN/A decode_block = BasicDecode.subst(iop) 2472526SN/A return (header_output, decoder_output, exec_output, decode_block) 2482526SN/A}}; 2492526SN/A 2502526SN/Adef format Priv(code, *opt_flags) {{ 2513587Sgblack@eecs.umich.edu checkCode = "!(Pstate<2:> || Hpstate<2:>)" 2522526SN/A (header_output, decoder_output, 2532526SN/A exec_output, decode_block) = doPrivFormat(code, 2543587Sgblack@eecs.umich.edu checkCode, name, Name, opt_flags) 2553587Sgblack@eecs.umich.edu}}; 2563587Sgblack@eecs.umich.edu 2573587Sgblack@eecs.umich.edudef format NoPriv(code, *opt_flags) {{ 2583587Sgblack@eecs.umich.edu #Instructions which use this format don't really check for 2593587Sgblack@eecs.umich.edu #any particular mode, but the disassembly is performed 2603587Sgblack@eecs.umich.edu #using the control registers actual name 2613587Sgblack@eecs.umich.edu checkCode = "false" 2623587Sgblack@eecs.umich.edu (header_output, decoder_output, 2633587Sgblack@eecs.umich.edu exec_output, decode_block) = doPrivFormat(code, 2643587Sgblack@eecs.umich.edu checkCode, name, Name, opt_flags) 2653587Sgblack@eecs.umich.edu}}; 2663587Sgblack@eecs.umich.edu 2673587Sgblack@eecs.umich.edudef format PrivCheck(code, extraCheckCode, *opt_flags) {{ 2683587Sgblack@eecs.umich.edu checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCheckCode 2693587Sgblack@eecs.umich.edu (header_output, decoder_output, 2703587Sgblack@eecs.umich.edu exec_output, decode_block) = doPrivFormat(code, 2713587Sgblack@eecs.umich.edu checkCode, name, Name, opt_flags) 2722469SN/A}}; 2732469SN/A 2742938Sgblack@eecs.umich.edudef format HPriv(code, *opt_flags) {{ 2753418Sgblack@eecs.umich.edu checkCode = "!Hpstate<2:2>" 2762938Sgblack@eecs.umich.edu (header_output, decoder_output, 2772938Sgblack@eecs.umich.edu exec_output, decode_block) = doPrivFormat(code, 2783587Sgblack@eecs.umich.edu checkCode, name, Name, opt_flags) 2792938Sgblack@eecs.umich.edu}}; 2802646Ssaidi@eecs.umich.edu 281