12083SN/A// -*- mode:c++ -*-
22083SN/A
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
302706Sksewell@umich.edu
312706Sksewell@umich.edu////////////////////////////////////////////////////////////////////
322706Sksewell@umich.edu//
332706Sksewell@umich.edu// Unimplemented instructions
342706Sksewell@umich.edu//
352649Ssaidi@eecs.umich.edu
362083SN/Aoutput header {{
372083SN/A    /**
382083SN/A     * Static instruction class for unimplemented instructions that
392083SN/A     * cause simulator termination.  Note that these are recognized
402083SN/A     * (legal) instructions that the simulator does not support; the
412083SN/A     * 'Unknown' class is used for unrecognized/illegal instructions.
422083SN/A     * This is a leaf class.
432083SN/A     */
442125SN/A    class FailUnimplemented : public MipsStaticInst
452083SN/A    {
462083SN/A      public:
472083SN/A        /// Constructor
482083SN/A        FailUnimplemented(const char *_mnemonic, MachInst _machInst)
492125SN/A            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
502083SN/A        {
512083SN/A            // don't call execute() (which panics) if we're on a
522083SN/A            // speculative path
532083SN/A            flags[IsNonSpeculative] = true;
542083SN/A        }
552083SN/A
5612616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
572083SN/A
5812616Sgabeblack@google.com        std::string generateDisassembly(
5912616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
602083SN/A    };
615222Sksewell@umich.edu    class CP0Unimplemented : public MipsStaticInst
625222Sksewell@umich.edu    {
635222Sksewell@umich.edu      public:
645222Sksewell@umich.edu        /// Constructor
655222Sksewell@umich.edu        CP0Unimplemented(const char *_mnemonic, MachInst _machInst)
665222Sksewell@umich.edu            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
675222Sksewell@umich.edu        {
685222Sksewell@umich.edu            // don't call execute() (which panics) if we're on a
695222Sksewell@umich.edu            // speculative path
705222Sksewell@umich.edu            flags[IsNonSpeculative] = true;
715222Sksewell@umich.edu        }
725222Sksewell@umich.edu
7312616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
745222Sksewell@umich.edu
7512616Sgabeblack@google.com        std::string generateDisassembly(
7612616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
775222Sksewell@umich.edu    };
785222Sksewell@umich.edu    class CP1Unimplemented : public MipsStaticInst
795222Sksewell@umich.edu    {
805222Sksewell@umich.edu      public:
815222Sksewell@umich.edu        /// Constructor
825222Sksewell@umich.edu        CP1Unimplemented(const char *_mnemonic, MachInst _machInst)
835222Sksewell@umich.edu            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
845222Sksewell@umich.edu        {
855222Sksewell@umich.edu            // don't call execute() (which panics) if we're on a
865222Sksewell@umich.edu            // speculative path
875222Sksewell@umich.edu            flags[IsNonSpeculative] = true;
885222Sksewell@umich.edu        }
895222Sksewell@umich.edu
9012616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
915222Sksewell@umich.edu
9212616Sgabeblack@google.com        std::string generateDisassembly(
9312616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
945222Sksewell@umich.edu    };
955222Sksewell@umich.edu    class CP2Unimplemented : public MipsStaticInst
965222Sksewell@umich.edu    {
975222Sksewell@umich.edu      public:
985222Sksewell@umich.edu        /// Constructor
995222Sksewell@umich.edu        CP2Unimplemented(const char *_mnemonic, MachInst _machInst)
1005222Sksewell@umich.edu            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
1015222Sksewell@umich.edu        {
1025222Sksewell@umich.edu            // don't call execute() (which panics) if we're on a
1035222Sksewell@umich.edu            // speculative path
1045222Sksewell@umich.edu            flags[IsNonSpeculative] = true;
1055222Sksewell@umich.edu        }
1065222Sksewell@umich.edu
10712616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
1085222Sksewell@umich.edu
10912616Sgabeblack@google.com        std::string generateDisassembly(
11012616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
1115222Sksewell@umich.edu    };
1122083SN/A
1132083SN/A    /**
1142083SN/A     * Base class for unimplemented instructions that cause a warning
1152083SN/A     * to be printed (but do not terminate simulation).  This
1162083SN/A     * implementation is a little screwy in that it will print a
1172083SN/A     * warning for each instance of a particular unimplemented machine
1182083SN/A     * instruction, not just for each unimplemented opcode.  Should
1192083SN/A     * probably make the 'warned' flag a static member of the derived
1202083SN/A     * class.
1212083SN/A     */
1222125SN/A    class WarnUnimplemented : public MipsStaticInst
1232083SN/A    {
1242083SN/A      private:
1252083SN/A        /// Have we warned on this instruction yet?
1262083SN/A        mutable bool warned;
1272083SN/A
1282083SN/A      public:
1292083SN/A        /// Constructor
1302083SN/A        WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
1312125SN/A            : MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
1322083SN/A        {
1332083SN/A            // don't call execute() (which panics) if we're on a
1342083SN/A            // speculative path
1352083SN/A            flags[IsNonSpeculative] = true;
1362083SN/A        }
1372083SN/A
13812616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
1392083SN/A
14012616Sgabeblack@google.com        std::string generateDisassembly(
14112616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
1422083SN/A    };
1432083SN/A}};
1442083SN/A
1452083SN/Aoutput decoder {{
1462083SN/A    std::string
1472083SN/A    FailUnimplemented::generateDisassembly(Addr pc,
1482083SN/A                                           const SymbolTable *symtab) const
1492083SN/A    {
1502083SN/A        return csprintf("%-10s (unimplemented)", mnemonic);
1512083SN/A    }
1522083SN/A
1532083SN/A    std::string
1545222Sksewell@umich.edu    CP0Unimplemented::generateDisassembly(Addr pc,
1555222Sksewell@umich.edu                                           const SymbolTable *symtab) const
1565222Sksewell@umich.edu    {
1575222Sksewell@umich.edu        return csprintf("%-10s (unimplemented)", mnemonic);
1585222Sksewell@umich.edu    }
1595222Sksewell@umich.edu
1605222Sksewell@umich.edu    std::string
1615222Sksewell@umich.edu    CP1Unimplemented::generateDisassembly(Addr pc,
1625222Sksewell@umich.edu                                           const SymbolTable *symtab) const
1635222Sksewell@umich.edu    {
1645222Sksewell@umich.edu        return csprintf("%-10s (unimplemented)", mnemonic);
1655222Sksewell@umich.edu    }
1665222Sksewell@umich.edu    std::string
1675222Sksewell@umich.edu    CP2Unimplemented::generateDisassembly(Addr pc,
1685222Sksewell@umich.edu                                           const SymbolTable *symtab) const
1695222Sksewell@umich.edu    {
1705222Sksewell@umich.edu        return csprintf("%-10s (unimplemented)", mnemonic);
1715222Sksewell@umich.edu    }
1725222Sksewell@umich.edu
1735222Sksewell@umich.edu    std::string
1742083SN/A    WarnUnimplemented::generateDisassembly(Addr pc,
1752083SN/A                                           const SymbolTable *symtab) const
1762083SN/A    {
1772083SN/A        return csprintf("%-10s (unimplemented)", mnemonic);
1782083SN/A    }
1792083SN/A}};
1802083SN/A
1812083SN/Aoutput exec {{
1822083SN/A    Fault
18312234Sgabeblack@google.com    FailUnimplemented::execute(ExecContext *xc,
1842083SN/A                               Trace::InstRecord *traceData) const
1852083SN/A    {
1862083SN/A        panic("attempt to execute unimplemented instruction '%s' "
1872495SN/A              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
1882495SN/A              inst2string(machInst));
1898568Sgblack@eecs.umich.edu        return NoFault;
1902083SN/A    }
1912083SN/A
1922083SN/A    Fault
19312234Sgabeblack@google.com    CP0Unimplemented::execute(ExecContext *xc,
1945222Sksewell@umich.edu                               Trace::InstRecord *traceData) const
1955222Sksewell@umich.edu    {
1968738Sgblack@eecs.umich.edu        if (FullSystem) {
1978564Sgblack@eecs.umich.edu            if (!isCoprocessorEnabled(xc, 0))
19810474Sandreas.hansson@arm.com                return std::make_shared<CoprocessorUnusableFault>(0);
1998564Sgblack@eecs.umich.edu            else
20010474Sandreas.hansson@arm.com                return std::make_shared<ReservedInstructionFault>();
2018564Sgblack@eecs.umich.edu        } else {
2028564Sgblack@eecs.umich.edu            panic("attempt to execute unimplemented instruction '%s' "
2038564Sgblack@eecs.umich.edu                    "(inst %#08x, opcode %#x, binary:%s)",
2048564Sgblack@eecs.umich.edu                    mnemonic, machInst, OPCODE, inst2string(machInst));
2058568Sgblack@eecs.umich.edu            return NoFault;
2068564Sgblack@eecs.umich.edu        }
2075222Sksewell@umich.edu    }
2085222Sksewell@umich.edu
2095222Sksewell@umich.edu    Fault
21012234Sgabeblack@google.com    CP1Unimplemented::execute(ExecContext *xc,
2115222Sksewell@umich.edu                               Trace::InstRecord *traceData) const
2125222Sksewell@umich.edu    {
2138738Sgblack@eecs.umich.edu        if (FullSystem) {
2148564Sgblack@eecs.umich.edu            if (!isCoprocessorEnabled(xc, 1))
21510474Sandreas.hansson@arm.com                return std::make_shared<CoprocessorUnusableFault>(1);
2168564Sgblack@eecs.umich.edu            else
21710474Sandreas.hansson@arm.com                return std::make_shared<ReservedInstructionFault>();
2188564Sgblack@eecs.umich.edu        } else {
2198564Sgblack@eecs.umich.edu            panic("attempt to execute unimplemented instruction '%s' "
2208564Sgblack@eecs.umich.edu                    "(inst %#08x, opcode %#x, binary:%s)",
2218564Sgblack@eecs.umich.edu                    mnemonic, machInst, OPCODE, inst2string(machInst));
2228568Sgblack@eecs.umich.edu            return NoFault;
2238564Sgblack@eecs.umich.edu        }
2245222Sksewell@umich.edu    }
2258564Sgblack@eecs.umich.edu
2265222Sksewell@umich.edu    Fault
22712234Sgabeblack@google.com    CP2Unimplemented::execute(ExecContext *xc,
2285222Sksewell@umich.edu                               Trace::InstRecord *traceData) const
2295222Sksewell@umich.edu    {
2308738Sgblack@eecs.umich.edu        if (FullSystem) {
2318564Sgblack@eecs.umich.edu            if (!isCoprocessorEnabled(xc, 2))
23210474Sandreas.hansson@arm.com                return std::make_shared<CoprocessorUnusableFault>(2);
2338564Sgblack@eecs.umich.edu            else
23410474Sandreas.hansson@arm.com                return std::make_shared<ReservedInstructionFault>();
2358564Sgblack@eecs.umich.edu        } else {
2368564Sgblack@eecs.umich.edu            panic("attempt to execute unimplemented instruction '%s' "
2378564Sgblack@eecs.umich.edu                    "(inst %#08x, opcode %#x, binary:%s)",
2388564Sgblack@eecs.umich.edu                    mnemonic, machInst, OPCODE, inst2string(machInst));
2398568Sgblack@eecs.umich.edu            return NoFault;
2408564Sgblack@eecs.umich.edu        }
2415222Sksewell@umich.edu    }
2425222Sksewell@umich.edu
2435222Sksewell@umich.edu    Fault
24412234Sgabeblack@google.com    WarnUnimplemented::execute(ExecContext *xc,
2452083SN/A                               Trace::InstRecord *traceData) const
2462083SN/A    {
2472083SN/A        if (!warned) {
2482686Sksewell@umich.edu            warn("\tinstruction '%s' unimplemented\n", mnemonic);
2492083SN/A            warned = true;
2502083SN/A        }
2512083SN/A
2522239SN/A        return NoFault;
2532083SN/A    }
2542083SN/A}};
2552083SN/A
2562083SN/A
2572083SN/Adef format FailUnimpl() {{
2582083SN/A    iop = InstObjParams(name, 'FailUnimplemented')
2592083SN/A    decode_block = BasicDecodeWithMnemonic.subst(iop)
2605222Sksewell@umich.edu
2612083SN/A}};
2625222Sksewell@umich.edudef format CP0Unimpl() {{
2635222Sksewell@umich.edu    iop = InstObjParams(name, 'CP0Unimplemented')
2645222Sksewell@umich.edu    decode_block = BasicDecodeWithMnemonic.subst(iop)
2655222Sksewell@umich.edu}};
2665222Sksewell@umich.edudef format CP1Unimpl() {{
2675222Sksewell@umich.edu    iop = InstObjParams(name, 'CP1Unimplemented')
2685222Sksewell@umich.edu    decode_block = BasicDecodeWithMnemonic.subst(iop)
2695222Sksewell@umich.edu}};
2705222Sksewell@umich.edudef format CP2Unimpl() {{
2715222Sksewell@umich.edu    iop = InstObjParams(name, 'CP2Unimplemented')
2725222Sksewell@umich.edu    decode_block = BasicDecodeWithMnemonic.subst(iop)
2735222Sksewell@umich.edu}};
2742083SN/Adef format WarnUnimpl() {{
2752083SN/A    iop = InstObjParams(name, 'WarnUnimplemented')
2762083SN/A    decode_block = BasicDecodeWithMnemonic.subst(iop)
2772083SN/A}};
2782083SN/A
279