control.isa revision 8800
12686Sksewell@umich.edu// -*- mode:c++ -*-
22686Sksewell@umich.edu
35268Sksewell@umich.edu// Copyright (c) 2007 MIPS Technologies, Inc.
45268Sksewell@umich.edu// All rights reserved.
55268Sksewell@umich.edu//
65268Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
75268Sksewell@umich.edu// modification, are permitted provided that the following conditions are
85268Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
95268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
105268Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
115268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
125268Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
135268Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
145268Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
155268Sksewell@umich.edu// this software without specific prior written permission.
165268Sksewell@umich.edu//
175268Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185268Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195268Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205268Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215268Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225268Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235268Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245268Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255268Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265268Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275268Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285268Sksewell@umich.edu//
295268Sksewell@umich.edu// Authors: Korey Sewell
305268Sksewell@umich.edu//          Jaidev Patwardhan
312706Sksewell@umich.edu
322686Sksewell@umich.edu////////////////////////////////////////////////////////////////////
332686Sksewell@umich.edu//
344661Sksewell@umich.edu// Coprocessor instructions
352686Sksewell@umich.edu//
362686Sksewell@umich.edu
372686Sksewell@umich.edu//Outputs to decoder.hh
382686Sksewell@umich.eduoutput header {{
392686Sksewell@umich.edu
404661Sksewell@umich.edu        class CP0Control : public MipsStaticInst
412686Sksewell@umich.edu        {
422686Sksewell@umich.edu                protected:
432686Sksewell@umich.edu
442686Sksewell@umich.edu                /// Constructor
454661Sksewell@umich.edu                CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
462686Sksewell@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
472686Sksewell@umich.edu                {
482686Sksewell@umich.edu                }
492686Sksewell@umich.edu
502686Sksewell@umich.edu                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
512686Sksewell@umich.edu        };
525222Sksewell@umich.edu        class CP0TLB : public MipsStaticInst
535222Sksewell@umich.edu        {
545222Sksewell@umich.edu                protected:
555222Sksewell@umich.edu
565222Sksewell@umich.edu                /// Constructor
575222Sksewell@umich.edu                CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
585222Sksewell@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
595222Sksewell@umich.edu                {
605222Sksewell@umich.edu                }
615222Sksewell@umich.edu
625222Sksewell@umich.edu                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
635222Sksewell@umich.edu        };
645222Sksewell@umich.edu
652686Sksewell@umich.edu
664661Sksewell@umich.edu        class CP1Control : public MipsStaticInst
672686Sksewell@umich.edu        {
682686Sksewell@umich.edu                protected:
692686Sksewell@umich.edu
702686Sksewell@umich.edu                /// Constructor
712686Sksewell@umich.edu                CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
724661Sksewell@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
732686Sksewell@umich.edu                {
742686Sksewell@umich.edu                }
752686Sksewell@umich.edu
762686Sksewell@umich.edu                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
772686Sksewell@umich.edu        };
782686Sksewell@umich.edu
792686Sksewell@umich.edu}};
802686Sksewell@umich.edu
814661Sksewell@umich.edu// Basic instruction class execute method template.
825222Sksewell@umich.edudef template CP0Execute {{
834661Sksewell@umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
844661Sksewell@umich.edu        {
854661Sksewell@umich.edu                Fault fault = NoFault;
864661Sksewell@umich.edu                %(op_decl)s;
874661Sksewell@umich.edu                %(op_rd)s;
884661Sksewell@umich.edu
894661Sksewell@umich.edu                if (isCoprocessorEnabled(xc, 0)) {
904661Sksewell@umich.edu                    %(code)s;
918800Sgblack@eecs.umich.edu
928800Sgblack@eecs.umich.edu                    if(fault == NoFault)
938800Sgblack@eecs.umich.edu                    {
948800Sgblack@eecs.umich.edu                        %(op_wb)s;
958800Sgblack@eecs.umich.edu                    }
964661Sksewell@umich.edu                } else {
975222Sksewell@umich.edu                    fault = new CoprocessorUnusableFault(0);
984661Sksewell@umich.edu                }
994661Sksewell@umich.edu                return fault;
1004661Sksewell@umich.edu        }
1014661Sksewell@umich.edu}};
1024661Sksewell@umich.edu
1035222Sksewell@umich.edudef template CP1Execute {{
1045222Sksewell@umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1055222Sksewell@umich.edu        {
1065222Sksewell@umich.edu                Fault fault = NoFault;
1075222Sksewell@umich.edu                %(op_decl)s;
1085222Sksewell@umich.edu                %(op_rd)s;
1095222Sksewell@umich.edu
1105222Sksewell@umich.edu                if (isCoprocessorEnabled(xc, 1)) {
1115222Sksewell@umich.edu                    %(code)s;
1125222Sksewell@umich.edu                } else {
1135222Sksewell@umich.edu                    fault = new CoprocessorUnusableFault(1);
1145222Sksewell@umich.edu                }
1155222Sksewell@umich.edu
1165222Sksewell@umich.edu                if(fault == NoFault)
1175222Sksewell@umich.edu                {
1185222Sksewell@umich.edu                    %(op_wb)s;
1195222Sksewell@umich.edu                }
1205222Sksewell@umich.edu                return fault;
1215222Sksewell@umich.edu        }
1225222Sksewell@umich.edu}};
1235222Sksewell@umich.edu// Basic instruction class execute method template.
1245222Sksewell@umich.edudef template ControlTLBExecute {{
1255222Sksewell@umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1265222Sksewell@umich.edu        {
1278564Sgblack@eecs.umich.edu            Fault fault = NoFault;
1288564Sgblack@eecs.umich.edu            %(op_decl)s;
1298564Sgblack@eecs.umich.edu            %(op_rd)s;
1305222Sksewell@umich.edu
1318738Sgblack@eecs.umich.edu            if (FullSystem) {
1325222Sksewell@umich.edu                if (isCoprocessor0Enabled(xc)) {
1338564Sgblack@eecs.umich.edu                    if(isMMUTLB(xc)){
1348564Sgblack@eecs.umich.edu                        %(code)s;
1358564Sgblack@eecs.umich.edu                    } else {
1368564Sgblack@eecs.umich.edu                        fault = new ReservedInstructionFault();
1378564Sgblack@eecs.umich.edu                    }
1385222Sksewell@umich.edu                } else {
1398564Sgblack@eecs.umich.edu                    fault = new CoprocessorUnusableFault(0);
1405222Sksewell@umich.edu                }
1418564Sgblack@eecs.umich.edu            } else { // Syscall Emulation Mode - No TLB Instructions
1425222Sksewell@umich.edu                fault = new ReservedInstructionFault();
1438564Sgblack@eecs.umich.edu            }
1445222Sksewell@umich.edu
1458564Sgblack@eecs.umich.edu            if (fault == NoFault) {
1468564Sgblack@eecs.umich.edu                %(op_wb)s;
1478564Sgblack@eecs.umich.edu            }
1488564Sgblack@eecs.umich.edu            return fault;
1495222Sksewell@umich.edu        }
1505222Sksewell@umich.edu}};
1515222Sksewell@umich.edu
1522686Sksewell@umich.edu//Outputs to decoder.cc
1532686Sksewell@umich.eduoutput decoder {{
1542686Sksewell@umich.edu        std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1552686Sksewell@umich.edu        {
1562686Sksewell@umich.edu            std::stringstream ss;
1574661Sksewell@umich.edu            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
1582686Sksewell@umich.edu            return ss.str();
1592686Sksewell@umich.edu        }
1605222Sksewell@umich.edu        std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1615222Sksewell@umich.edu        {
1625222Sksewell@umich.edu            std::stringstream ss;
1635222Sksewell@umich.edu            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
1645222Sksewell@umich.edu            return ss.str();
1655222Sksewell@umich.edu        }
1662686Sksewell@umich.edu        std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1672686Sksewell@umich.edu        {
1682686Sksewell@umich.edu            std::stringstream ss;
1692686Sksewell@umich.edu            ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
1702686Sksewell@umich.edu            return ss.str();
1712686Sksewell@umich.edu        }
1722686Sksewell@umich.edu
1732686Sksewell@umich.edu}};
1742686Sksewell@umich.edu
1754661Sksewell@umich.eduoutput exec {{
1768564Sgblack@eecs.umich.edu        bool
1778564Sgblack@eecs.umich.edu        isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
1784661Sksewell@umich.edu        {
1798738Sgblack@eecs.umich.edu            if (!FullSystem)
1808564Sgblack@eecs.umich.edu                return true;
1815224Sksewell@umich.edu
1828564Sgblack@eecs.umich.edu            MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
1838564Sgblack@eecs.umich.edu            if (cop_num == 0) {
1848564Sgblack@eecs.umich.edu                MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
1858564Sgblack@eecs.umich.edu                // In Stat, EXL, ERL or CU0 set, CP0 accessible
1868564Sgblack@eecs.umich.edu                // In Dbg, DM bit set, CP0 accessible
1878564Sgblack@eecs.umich.edu                // In Stat, KSU = 0, kernel mode is base mode
1888564Sgblack@eecs.umich.edu                return (Stat & 0x10000006) ||
1898564Sgblack@eecs.umich.edu                       (Dbg & 0x40000000) ||
1908564Sgblack@eecs.umich.edu                       !(Stat & 0x00000018);
1918564Sgblack@eecs.umich.edu            } else if (cop_num < 4) {
1928564Sgblack@eecs.umich.edu                return Stat & (0x10000000 << cop_num); // CU is reset
1938564Sgblack@eecs.umich.edu            } else {
1948564Sgblack@eecs.umich.edu                panic("Invalid Coprocessor Number Specified");
1954661Sksewell@umich.edu            }
1964661Sksewell@umich.edu        }
1978564Sgblack@eecs.umich.edu
1988564Sgblack@eecs.umich.edu        bool inline
1998564Sgblack@eecs.umich.edu        isCoprocessor0Enabled(%(CPU_exec_context)s *xc)
2005222Sksewell@umich.edu        {
2018738Sgblack@eecs.umich.edu            if (FullSystem) {
2028564Sgblack@eecs.umich.edu                MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
2038564Sgblack@eecs.umich.edu                MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
2048564Sgblack@eecs.umich.edu                // In Stat, EXL, ERL or CU0 set, CP0 accessible
2058564Sgblack@eecs.umich.edu                // In Dbg, DM bit set, CP0 accessible
2068564Sgblack@eecs.umich.edu                // In Stat KSU = 0, kernel mode is base mode
2078564Sgblack@eecs.umich.edu                return (Stat & 0x10000006) || (Dbg & 0x40000000) ||
2088564Sgblack@eecs.umich.edu                    !(Stat & 0x00000018);
2098564Sgblack@eecs.umich.edu            } else {
2108564Sgblack@eecs.umich.edu                return true;
2118564Sgblack@eecs.umich.edu            }
2125222Sksewell@umich.edu        }
2138564Sgblack@eecs.umich.edu
2148564Sgblack@eecs.umich.edu        bool
2158564Sgblack@eecs.umich.edu        isMMUTLB(%(CPU_exec_context)s *xc)
2165222Sksewell@umich.edu        {
2178564Sgblack@eecs.umich.edu            MiscReg Config = xc->readMiscReg(MISCREG_CONFIG);
2188738Sgblack@eecs.umich.edu            return FullSystem && (Config & 0x380) == 0x80;
2195222Sksewell@umich.edu        }
2202686Sksewell@umich.edu}};
2212686Sksewell@umich.edu
2222686Sksewell@umich.edudef format CP0Control(code, *flags) {{
2234661Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2244661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
2254661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2264661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2274661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2285222Sksewell@umich.edu    exec_output = CP0Execute.subst(iop)
2292686Sksewell@umich.edu}};
2305222Sksewell@umich.edudef format CP0TLB(code, *flags) {{
2315222Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2325222Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
2335222Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2345222Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2355222Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2365222Sksewell@umich.edu    exec_output = ControlTLBExecute.subst(iop)
2375222Sksewell@umich.edu}};
2382686Sksewell@umich.edudef format CP1Control(code, *flags) {{
2394661Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2404661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP1Control', code, flags)
2414661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2424661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2434661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2445222Sksewell@umich.edu    exec_output = CP1Execute.subst(iop)
2452686Sksewell@umich.edu}};
2462686Sksewell@umich.edu
2472686Sksewell@umich.edu
248