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