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
5012616Sgabeblack@google.com                std::string generateDisassembly(
5112616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
522686Sksewell@umich.edu        };
535222Sksewell@umich.edu        class CP0TLB : public MipsStaticInst
545222Sksewell@umich.edu        {
555222Sksewell@umich.edu                protected:
565222Sksewell@umich.edu
575222Sksewell@umich.edu                /// Constructor
585222Sksewell@umich.edu                CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
595222Sksewell@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
605222Sksewell@umich.edu                {
615222Sksewell@umich.edu                }
625222Sksewell@umich.edu
6312616Sgabeblack@google.com                std::string generateDisassembly(
6412616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
655222Sksewell@umich.edu        };
665222Sksewell@umich.edu
672686Sksewell@umich.edu
684661Sksewell@umich.edu        class CP1Control : public MipsStaticInst
692686Sksewell@umich.edu        {
702686Sksewell@umich.edu                protected:
712686Sksewell@umich.edu
722686Sksewell@umich.edu                /// Constructor
732686Sksewell@umich.edu                CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
744661Sksewell@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
752686Sksewell@umich.edu                {
762686Sksewell@umich.edu                }
772686Sksewell@umich.edu
7812616Sgabeblack@google.com                std::string generateDisassembly(
7912616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
802686Sksewell@umich.edu        };
812686Sksewell@umich.edu
822686Sksewell@umich.edu}};
832686Sksewell@umich.edu
844661Sksewell@umich.edu// Basic instruction class execute method template.
855222Sksewell@umich.edudef template CP0Execute {{
8612234Sgabeblack@google.com        Fault %(class_name)s::execute(
8712234Sgabeblack@google.com            ExecContext *xc, Trace::InstRecord *traceData) const
884661Sksewell@umich.edu        {
894661Sksewell@umich.edu                Fault fault = NoFault;
904661Sksewell@umich.edu                %(op_decl)s;
914661Sksewell@umich.edu                %(op_rd)s;
924661Sksewell@umich.edu
934661Sksewell@umich.edu                if (isCoprocessorEnabled(xc, 0)) {
944661Sksewell@umich.edu                    %(code)s;
958800Sgblack@eecs.umich.edu
968800Sgblack@eecs.umich.edu                    if(fault == NoFault)
978800Sgblack@eecs.umich.edu                    {
988800Sgblack@eecs.umich.edu                        %(op_wb)s;
998800Sgblack@eecs.umich.edu                    }
1004661Sksewell@umich.edu                } else {
10110474Sandreas.hansson@arm.com                    fault = std::make_shared<CoprocessorUnusableFault>(0);
1024661Sksewell@umich.edu                }
1034661Sksewell@umich.edu                return fault;
1044661Sksewell@umich.edu        }
1054661Sksewell@umich.edu}};
1064661Sksewell@umich.edu
1075222Sksewell@umich.edudef template CP1Execute {{
10812234Sgabeblack@google.com        Fault %(class_name)s::execute(
10912234Sgabeblack@google.com            ExecContext *xc, Trace::InstRecord *traceData) const
1105222Sksewell@umich.edu        {
1115222Sksewell@umich.edu                Fault fault = NoFault;
1125222Sksewell@umich.edu                %(op_decl)s;
1135222Sksewell@umich.edu                %(op_rd)s;
1145222Sksewell@umich.edu
1155222Sksewell@umich.edu                if (isCoprocessorEnabled(xc, 1)) {
1165222Sksewell@umich.edu                    %(code)s;
1175222Sksewell@umich.edu                } else {
11810474Sandreas.hansson@arm.com                    fault = std::make_shared<CoprocessorUnusableFault>(1);
1195222Sksewell@umich.edu                }
1205222Sksewell@umich.edu
1215222Sksewell@umich.edu                if(fault == NoFault)
1225222Sksewell@umich.edu                {
1235222Sksewell@umich.edu                    %(op_wb)s;
1245222Sksewell@umich.edu                }
1255222Sksewell@umich.edu                return fault;
1265222Sksewell@umich.edu        }
1275222Sksewell@umich.edu}};
1285222Sksewell@umich.edu// Basic instruction class execute method template.
1295222Sksewell@umich.edudef template ControlTLBExecute {{
13012234Sgabeblack@google.com        Fault %(class_name)s::execute(
13112234Sgabeblack@google.com            ExecContext *xc, Trace::InstRecord *traceData) const
1325222Sksewell@umich.edu        {
1338564Sgblack@eecs.umich.edu            Fault fault = NoFault;
1348564Sgblack@eecs.umich.edu            %(op_decl)s;
1358564Sgblack@eecs.umich.edu            %(op_rd)s;
1365222Sksewell@umich.edu
1378738Sgblack@eecs.umich.edu            if (FullSystem) {
1385222Sksewell@umich.edu                if (isCoprocessor0Enabled(xc)) {
1398564Sgblack@eecs.umich.edu                    if(isMMUTLB(xc)){
1408564Sgblack@eecs.umich.edu                        %(code)s;
1418564Sgblack@eecs.umich.edu                    } else {
14210474Sandreas.hansson@arm.com                        fault = std::make_shared<ReservedInstructionFault>();
1438564Sgblack@eecs.umich.edu                    }
1445222Sksewell@umich.edu                } else {
14510474Sandreas.hansson@arm.com                    fault = std::make_shared<CoprocessorUnusableFault>(0);
1465222Sksewell@umich.edu                }
1478564Sgblack@eecs.umich.edu            } else { // Syscall Emulation Mode - No TLB Instructions
14810474Sandreas.hansson@arm.com                fault = std::make_shared<ReservedInstructionFault>();
1498564Sgblack@eecs.umich.edu            }
1505222Sksewell@umich.edu
1518564Sgblack@eecs.umich.edu            if (fault == NoFault) {
1528564Sgblack@eecs.umich.edu                %(op_wb)s;
1538564Sgblack@eecs.umich.edu            }
1548564Sgblack@eecs.umich.edu            return fault;
1555222Sksewell@umich.edu        }
1565222Sksewell@umich.edu}};
1575222Sksewell@umich.edu
1582686Sksewell@umich.edu//Outputs to decoder.cc
1592686Sksewell@umich.eduoutput decoder {{
1602686Sksewell@umich.edu        std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1612686Sksewell@umich.edu        {
1622686Sksewell@umich.edu            std::stringstream ss;
1634661Sksewell@umich.edu            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
1642686Sksewell@umich.edu            return ss.str();
1652686Sksewell@umich.edu        }
1665222Sksewell@umich.edu        std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1675222Sksewell@umich.edu        {
1685222Sksewell@umich.edu            std::stringstream ss;
1695222Sksewell@umich.edu            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
1705222Sksewell@umich.edu            return ss.str();
1715222Sksewell@umich.edu        }
1722686Sksewell@umich.edu        std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1732686Sksewell@umich.edu        {
1742686Sksewell@umich.edu            std::stringstream ss;
1752686Sksewell@umich.edu            ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
1762686Sksewell@umich.edu            return ss.str();
1772686Sksewell@umich.edu        }
1782686Sksewell@umich.edu
1792686Sksewell@umich.edu}};
1802686Sksewell@umich.edu
1819554Sandreas.hansson@arm.comoutput header {{
18212234Sgabeblack@google.com        bool isCoprocessorEnabled(ExecContext *xc, unsigned cop_num);
1839554Sandreas.hansson@arm.com
18412234Sgabeblack@google.com        bool isMMUTLB(ExecContext *xc);
1859554Sandreas.hansson@arm.com
1869554Sandreas.hansson@arm.com}};
1879554Sandreas.hansson@arm.com
1884661Sksewell@umich.eduoutput exec {{
1898564Sgblack@eecs.umich.edu        bool
19012234Sgabeblack@google.com        isCoprocessorEnabled(ExecContext *xc, unsigned cop_num)
1914661Sksewell@umich.edu        {
1928738Sgblack@eecs.umich.edu            if (!FullSystem)
1938564Sgblack@eecs.umich.edu                return true;
1945224Sksewell@umich.edu
19513615Sgabeblack@google.com            RegVal Stat = xc->readMiscReg(MISCREG_STATUS);
1968564Sgblack@eecs.umich.edu            if (cop_num == 0) {
19713615Sgabeblack@google.com                RegVal Dbg = xc->readMiscReg(MISCREG_DEBUG);
1988564Sgblack@eecs.umich.edu                // In Stat, EXL, ERL or CU0 set, CP0 accessible
1998564Sgblack@eecs.umich.edu                // In Dbg, DM bit set, CP0 accessible
2008564Sgblack@eecs.umich.edu                // In Stat, KSU = 0, kernel mode is base mode
2018564Sgblack@eecs.umich.edu                return (Stat & 0x10000006) ||
2028564Sgblack@eecs.umich.edu                       (Dbg & 0x40000000) ||
2038564Sgblack@eecs.umich.edu                       !(Stat & 0x00000018);
2048564Sgblack@eecs.umich.edu            } else if (cop_num < 4) {
2058564Sgblack@eecs.umich.edu                return Stat & (0x10000000 << cop_num); // CU is reset
2068564Sgblack@eecs.umich.edu            } else {
2078564Sgblack@eecs.umich.edu                panic("Invalid Coprocessor Number Specified");
2084661Sksewell@umich.edu            }
2094661Sksewell@umich.edu        }
2108564Sgblack@eecs.umich.edu
2118564Sgblack@eecs.umich.edu        bool inline
21212234Sgabeblack@google.com        isCoprocessor0Enabled(ExecContext *xc)
2135222Sksewell@umich.edu        {
2148738Sgblack@eecs.umich.edu            if (FullSystem) {
21513615Sgabeblack@google.com                RegVal Stat = xc->readMiscReg(MISCREG_STATUS);
21613615Sgabeblack@google.com                RegVal Dbg = xc->readMiscReg(MISCREG_DEBUG);
2178564Sgblack@eecs.umich.edu                // In Stat, EXL, ERL or CU0 set, CP0 accessible
2188564Sgblack@eecs.umich.edu                // In Dbg, DM bit set, CP0 accessible
2198564Sgblack@eecs.umich.edu                // In Stat KSU = 0, kernel mode is base mode
2208564Sgblack@eecs.umich.edu                return (Stat & 0x10000006) || (Dbg & 0x40000000) ||
2218564Sgblack@eecs.umich.edu                    !(Stat & 0x00000018);
2228564Sgblack@eecs.umich.edu            } else {
2238564Sgblack@eecs.umich.edu                return true;
2248564Sgblack@eecs.umich.edu            }
2255222Sksewell@umich.edu        }
2268564Sgblack@eecs.umich.edu
2278564Sgblack@eecs.umich.edu        bool
22812234Sgabeblack@google.com        isMMUTLB(ExecContext *xc)
2295222Sksewell@umich.edu        {
23013615Sgabeblack@google.com            RegVal Config = xc->readMiscReg(MISCREG_CONFIG);
2318738Sgblack@eecs.umich.edu            return FullSystem && (Config & 0x380) == 0x80;
2325222Sksewell@umich.edu        }
2332686Sksewell@umich.edu}};
2342686Sksewell@umich.edu
2352686Sksewell@umich.edudef format CP0Control(code, *flags) {{
2364661Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2374661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
2384661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2394661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2404661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2415222Sksewell@umich.edu    exec_output = CP0Execute.subst(iop)
2422686Sksewell@umich.edu}};
2435222Sksewell@umich.edudef format CP0TLB(code, *flags) {{
2445222Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2455222Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
2465222Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2475222Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2485222Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2495222Sksewell@umich.edu    exec_output = ControlTLBExecute.subst(iop)
2505222Sksewell@umich.edu}};
2512686Sksewell@umich.edudef format CP1Control(code, *flags) {{
2524661Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2534661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP1Control', code, flags)
2544661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2554661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2564661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2575222Sksewell@umich.edu    exec_output = CP1Execute.subst(iop)
2582686Sksewell@umich.edu}};
2592686Sksewell@umich.edu
2602686Sksewell@umich.edu
261