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