priv.isa revision 5094
15094Sgblack@eecs.umich.edu// Copyright (c) 2006-2007 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, " "); 1563627Sgblack@eecs.umich.edu //If the first reg is %g0, don't print it. 1573627Sgblack@eecs.umich.edu //This improves readability 1583627Sgblack@eecs.umich.edu if(_srcRegIdx[0] != 0) 1593627Sgblack@eecs.umich.edu { 1603627Sgblack@eecs.umich.edu printSrcReg(response, 0); 1613627Sgblack@eecs.umich.edu ccprintf(response, ", "); 1623627Sgblack@eecs.umich.edu } 1633599Sgblack@eecs.umich.edu printSrcReg(response, 1); 1643599Sgblack@eecs.umich.edu ccprintf(response, ", %%%s", regName); 1653599Sgblack@eecs.umich.edu 1663599Sgblack@eecs.umich.edu return response.str(); 1673599Sgblack@eecs.umich.edu } 1683599Sgblack@eecs.umich.edu 1693599Sgblack@eecs.umich.edu std::string WrPrivImm::generateDisassembly(Addr pc, 1703599Sgblack@eecs.umich.edu const SymbolTable *symtab) const 1713599Sgblack@eecs.umich.edu { 1723599Sgblack@eecs.umich.edu std::stringstream response; 1733599Sgblack@eecs.umich.edu 1743599Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 1753599Sgblack@eecs.umich.edu 1763599Sgblack@eecs.umich.edu ccprintf(response, " "); 1773627Sgblack@eecs.umich.edu //If the first reg is %g0, don't print it. 1783627Sgblack@eecs.umich.edu //This improves readability 1793627Sgblack@eecs.umich.edu if(_srcRegIdx[0] != 0) 1803627Sgblack@eecs.umich.edu { 1813627Sgblack@eecs.umich.edu printSrcReg(response, 0); 1823627Sgblack@eecs.umich.edu ccprintf(response, ", "); 1833627Sgblack@eecs.umich.edu } 1843627Sgblack@eecs.umich.edu ccprintf(response, "0x%x, %%%s", imm, regName); 1853599Sgblack@eecs.umich.edu 1863599Sgblack@eecs.umich.edu return response.str(); 1873599Sgblack@eecs.umich.edu } 1883599Sgblack@eecs.umich.edu}}; 1893599Sgblack@eecs.umich.edu 1903599Sgblack@eecs.umich.edudef template ControlRegConstructor {{ 1913599Sgblack@eecs.umich.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 1923599Sgblack@eecs.umich.edu : %(base_class)s("%(mnemonic)s", machInst, 1933599Sgblack@eecs.umich.edu %(op_class)s, "%(reg_name)s") 1943599Sgblack@eecs.umich.edu { 1953599Sgblack@eecs.umich.edu %(constructor)s; 1963599Sgblack@eecs.umich.edu } 1972469SN/A}}; 1982469SN/A 1992469SN/Adef template PrivExecute {{ 2002469SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2012469SN/A Trace::InstRecord *traceData) const 2022469SN/A { 2032469SN/A %(op_decl)s; 2042469SN/A %(op_rd)s; 2052469SN/A 2062469SN/A //If the processor isn't in privileged mode, fault out right away 2072526SN/A if(%(check)s) 2082488SN/A return new PrivilegedAction; 2092469SN/A 2105094Sgblack@eecs.umich.edu if(%(tlCheck)s) 2115094Sgblack@eecs.umich.edu return new IllegalInstruction; 2125094Sgblack@eecs.umich.edu 2132938Sgblack@eecs.umich.edu Fault fault = NoFault; 2142469SN/A %(code)s; 2152469SN/A %(op_wb)s; 2162938Sgblack@eecs.umich.edu return fault; 2172469SN/A } 2182469SN/A}}; 2192469SN/A 2202526SN/Alet {{ 2215094Sgblack@eecs.umich.edu def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags): 2222526SN/A (usesImm, code, immCode, 2232526SN/A rString, iString) = splitOutImm(code) 2243599Sgblack@eecs.umich.edu #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions, 2253599Sgblack@eecs.umich.edu #cut any other info out of the mnemonic. Also pick a different 2263599Sgblack@eecs.umich.edu #base class. 2273599Sgblack@eecs.umich.edu regBase = 'Priv' 2283599Sgblack@eecs.umich.edu regName = '' 2293599Sgblack@eecs.umich.edu for mnem in ["rdhpr", "rdpr", "rd"]: 2303599Sgblack@eecs.umich.edu if name.startswith(mnem): 2313599Sgblack@eecs.umich.edu regName = name[len(mnem):] 2323599Sgblack@eecs.umich.edu name = mnem 2333599Sgblack@eecs.umich.edu regBase = 'RdPriv' 2343599Sgblack@eecs.umich.edu break 2353599Sgblack@eecs.umich.edu for mnem in ["wrhpr", "wrpr", "wr"]: 2363599Sgblack@eecs.umich.edu if name.startswith(mnem): 2373599Sgblack@eecs.umich.edu regName = name[len(mnem):] 2383599Sgblack@eecs.umich.edu name = mnem 2393599Sgblack@eecs.umich.edu regBase = 'WrPriv' 2403599Sgblack@eecs.umich.edu break 2413792Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, regBase, 2425094Sgblack@eecs.umich.edu {"code": code, "check": checkCode, 2435094Sgblack@eecs.umich.edu "tlCheck": tlCheck, "reg_name": regName}, 2443792Sgblack@eecs.umich.edu opt_flags) 2452469SN/A header_output = BasicDeclare.subst(iop) 2463599Sgblack@eecs.umich.edu if regName == '': 2473599Sgblack@eecs.umich.edu decoder_output = BasicConstructor.subst(iop) 2483599Sgblack@eecs.umich.edu else: 2493599Sgblack@eecs.umich.edu decoder_output = ControlRegConstructor.subst(iop) 2502469SN/A exec_output = PrivExecute.subst(iop) 2512526SN/A if usesImm: 2523599Sgblack@eecs.umich.edu imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', 2535094Sgblack@eecs.umich.edu {"code": immCode, "check": checkCode, 2545094Sgblack@eecs.umich.edu "tlCheck": tlCheck, "reg_name": regName}, 2553792Sgblack@eecs.umich.edu opt_flags) 2562469SN/A header_output += BasicDeclare.subst(imm_iop) 2573599Sgblack@eecs.umich.edu if regName == '': 2583599Sgblack@eecs.umich.edu decoder_output += BasicConstructor.subst(imm_iop) 2593599Sgblack@eecs.umich.edu else: 2603599Sgblack@eecs.umich.edu decoder_output += ControlRegConstructor.subst(imm_iop) 2612469SN/A exec_output += PrivExecute.subst(imm_iop) 2622482SN/A decode_block = ROrImmDecode.subst(iop) 2632469SN/A else: 2642469SN/A decode_block = BasicDecode.subst(iop) 2652526SN/A return (header_output, decoder_output, exec_output, decode_block) 2662526SN/A}}; 2672526SN/A 2685094Sgblack@eecs.umich.edudef format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{ 2695094Sgblack@eecs.umich.edu checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCond 2705094Sgblack@eecs.umich.edu if checkTl != "false": 2715094Sgblack@eecs.umich.edu tlCheck = "Tl == 0" 2725094Sgblack@eecs.umich.edu else: 2735094Sgblack@eecs.umich.edu tlCheck = "false" 2742526SN/A (header_output, decoder_output, 2752526SN/A exec_output, decode_block) = doPrivFormat(code, 2765094Sgblack@eecs.umich.edu checkCode, name, Name, tlCheck, opt_flags) 2773587Sgblack@eecs.umich.edu}}; 2783587Sgblack@eecs.umich.edu 2795094Sgblack@eecs.umich.edudef format NoPriv(code, checkTl=false, *opt_flags) {{ 2803587Sgblack@eecs.umich.edu #Instructions which use this format don't really check for 2813587Sgblack@eecs.umich.edu #any particular mode, but the disassembly is performed 2823587Sgblack@eecs.umich.edu #using the control registers actual name 2833587Sgblack@eecs.umich.edu checkCode = "false" 2845094Sgblack@eecs.umich.edu if checkTl != "false": 2855094Sgblack@eecs.umich.edu tlCheck = "Tl == 0" 2865094Sgblack@eecs.umich.edu else: 2875094Sgblack@eecs.umich.edu tlCheck = "false" 2883587Sgblack@eecs.umich.edu (header_output, decoder_output, 2893587Sgblack@eecs.umich.edu exec_output, decode_block) = doPrivFormat(code, 2905094Sgblack@eecs.umich.edu checkCode, name, Name, tlCheck, opt_flags) 2913587Sgblack@eecs.umich.edu}}; 2923587Sgblack@eecs.umich.edu 2935094Sgblack@eecs.umich.edudef format HPriv(code, checkTl=false, *opt_flags) {{ 2945094Sgblack@eecs.umich.edu checkCode = "!Hpstate<2:2>" 2955094Sgblack@eecs.umich.edu if checkTl != "false": 2965094Sgblack@eecs.umich.edu tlCheck = "Tl == 0" 2975094Sgblack@eecs.umich.edu else: 2985094Sgblack@eecs.umich.edu tlCheck = "false" 2993587Sgblack@eecs.umich.edu (header_output, decoder_output, 3003587Sgblack@eecs.umich.edu exec_output, decode_block) = doPrivFormat(code, 3015094Sgblack@eecs.umich.edu checkCode, name, Name, tlCheck, opt_flags) 3022469SN/A}}; 3032469SN/A 304