16691Stjones1@inf.ed.ac.uk// -*- mode:c++ -*-
26691Stjones1@inf.ed.ac.uk
36691Stjones1@inf.ed.ac.uk// Copyright (c) 2007-2008 The Florida State University
46691Stjones1@inf.ed.ac.uk// Copyright (c) 2009 The University of Edinburgh
56691Stjones1@inf.ed.ac.uk// All rights reserved.
66691Stjones1@inf.ed.ac.uk//
76691Stjones1@inf.ed.ac.uk// Redistribution and use in source and binary forms, with or without
86691Stjones1@inf.ed.ac.uk// modification, are permitted provided that the following conditions are
96691Stjones1@inf.ed.ac.uk// met: redistributions of source code must retain the above copyright
106691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer;
116691Stjones1@inf.ed.ac.uk// redistributions in binary form must reproduce the above copyright
126691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer in the
136691Stjones1@inf.ed.ac.uk// documentation and/or other materials provided with the distribution;
146691Stjones1@inf.ed.ac.uk// neither the name of the copyright holders nor the names of its
156691Stjones1@inf.ed.ac.uk// contributors may be used to endorse or promote products derived from
166691Stjones1@inf.ed.ac.uk// this software without specific prior written permission.
176691Stjones1@inf.ed.ac.uk//
186691Stjones1@inf.ed.ac.uk// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
196691Stjones1@inf.ed.ac.uk// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
206691Stjones1@inf.ed.ac.uk// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
216691Stjones1@inf.ed.ac.uk// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
226691Stjones1@inf.ed.ac.uk// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
236691Stjones1@inf.ed.ac.uk// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
246691Stjones1@inf.ed.ac.uk// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
256691Stjones1@inf.ed.ac.uk// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
266691Stjones1@inf.ed.ac.uk// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
276691Stjones1@inf.ed.ac.uk// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
286691Stjones1@inf.ed.ac.uk// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
296691Stjones1@inf.ed.ac.uk//
306691Stjones1@inf.ed.ac.uk// Authors: Stephen Hines
316691Stjones1@inf.ed.ac.uk//          Timothy M. Jones
326691Stjones1@inf.ed.ac.uk
336691Stjones1@inf.ed.ac.uk////////////////////////////////////////////////////////////////////
346691Stjones1@inf.ed.ac.uk//
356691Stjones1@inf.ed.ac.uk// Unimplemented instructions
366691Stjones1@inf.ed.ac.uk//
376691Stjones1@inf.ed.ac.uk
386691Stjones1@inf.ed.ac.ukoutput header {{
396691Stjones1@inf.ed.ac.uk    /**
406691Stjones1@inf.ed.ac.uk     * Static instruction class for unimplemented instructions that
416691Stjones1@inf.ed.ac.uk     * cause simulator termination.  Note that these are recognized
426691Stjones1@inf.ed.ac.uk     * (legal) instructions that the simulator does not support; the
436691Stjones1@inf.ed.ac.uk     * 'Unknown' class is used for unrecognized/illegal instructions.
446691Stjones1@inf.ed.ac.uk     * This is a leaf class.
456691Stjones1@inf.ed.ac.uk     */
466691Stjones1@inf.ed.ac.uk    class FailUnimplemented : public PowerStaticInst
476691Stjones1@inf.ed.ac.uk    {
486691Stjones1@inf.ed.ac.uk      public:
496691Stjones1@inf.ed.ac.uk        /// Constructor
506691Stjones1@inf.ed.ac.uk        FailUnimplemented(const char *_mnemonic, MachInst _machInst)
516691Stjones1@inf.ed.ac.uk            : PowerStaticInst(_mnemonic, _machInst, No_OpClass)
526691Stjones1@inf.ed.ac.uk        {
536691Stjones1@inf.ed.ac.uk            // don't call execute() (which panics) if we're on a
546691Stjones1@inf.ed.ac.uk            // speculative path
556691Stjones1@inf.ed.ac.uk            flags[IsNonSpeculative] = true;
566691Stjones1@inf.ed.ac.uk        }
576691Stjones1@inf.ed.ac.uk
5812616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
596691Stjones1@inf.ed.ac.uk
6012616Sgabeblack@google.com        std::string generateDisassembly(
6112616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
626691Stjones1@inf.ed.ac.uk    };
636691Stjones1@inf.ed.ac.uk
646691Stjones1@inf.ed.ac.uk    /**
656691Stjones1@inf.ed.ac.uk     * Base class for unimplemented instructions that cause a warning
666691Stjones1@inf.ed.ac.uk     * to be printed (but do not terminate simulation).  This
676691Stjones1@inf.ed.ac.uk     * implementation is a little screwy in that it will print a
686691Stjones1@inf.ed.ac.uk     * warning for each instance of a particular unimplemented machine
696691Stjones1@inf.ed.ac.uk     * instruction, not just for each unimplemented opcode.  Should
706691Stjones1@inf.ed.ac.uk     * probably make the 'warned' flag a static member of the derived
716691Stjones1@inf.ed.ac.uk     * class.
726691Stjones1@inf.ed.ac.uk     */
736691Stjones1@inf.ed.ac.uk    class WarnUnimplemented : public PowerStaticInst
746691Stjones1@inf.ed.ac.uk    {
756691Stjones1@inf.ed.ac.uk      private:
766691Stjones1@inf.ed.ac.uk        /// Have we warned on this instruction yet?
776691Stjones1@inf.ed.ac.uk        mutable bool warned;
786691Stjones1@inf.ed.ac.uk
796691Stjones1@inf.ed.ac.uk      public:
806691Stjones1@inf.ed.ac.uk        /// Constructor
816691Stjones1@inf.ed.ac.uk        WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
826691Stjones1@inf.ed.ac.uk            : PowerStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
836691Stjones1@inf.ed.ac.uk        {
846691Stjones1@inf.ed.ac.uk            // don't call execute() (which panics) if we're on a
856691Stjones1@inf.ed.ac.uk            // speculative path
866691Stjones1@inf.ed.ac.uk            flags[IsNonSpeculative] = true;
876691Stjones1@inf.ed.ac.uk        }
886691Stjones1@inf.ed.ac.uk
8912616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
906691Stjones1@inf.ed.ac.uk
9112616Sgabeblack@google.com        std::string generateDisassembly(
9212616Sgabeblack@google.com                Addr pc, const SymbolTable *symtab) const override;
936691Stjones1@inf.ed.ac.uk    };
946691Stjones1@inf.ed.ac.uk}};
956691Stjones1@inf.ed.ac.uk
966691Stjones1@inf.ed.ac.ukoutput decoder {{
976691Stjones1@inf.ed.ac.uk    std::string
986691Stjones1@inf.ed.ac.uk    FailUnimplemented::generateDisassembly(Addr pc,
996691Stjones1@inf.ed.ac.uk                                           const SymbolTable *symtab) const
1006691Stjones1@inf.ed.ac.uk    {
1016691Stjones1@inf.ed.ac.uk        return csprintf("%-10s (unimplemented)", mnemonic);
1026691Stjones1@inf.ed.ac.uk    }
1036691Stjones1@inf.ed.ac.uk
1046691Stjones1@inf.ed.ac.uk    std::string
1056691Stjones1@inf.ed.ac.uk    WarnUnimplemented::generateDisassembly(Addr pc,
1066691Stjones1@inf.ed.ac.uk                                           const SymbolTable *symtab) const
1076691Stjones1@inf.ed.ac.uk    {
1086691Stjones1@inf.ed.ac.uk        return csprintf("%-10s (unimplemented)", mnemonic);
1096691Stjones1@inf.ed.ac.uk    }
1106691Stjones1@inf.ed.ac.uk}};
1116691Stjones1@inf.ed.ac.uk
1126691Stjones1@inf.ed.ac.ukoutput exec {{
1136691Stjones1@inf.ed.ac.uk    Fault
11412234Sgabeblack@google.com    FailUnimplemented::execute(ExecContext *xc,
1156691Stjones1@inf.ed.ac.uk                               Trace::InstRecord *traceData) const
1166691Stjones1@inf.ed.ac.uk    {
1176691Stjones1@inf.ed.ac.uk        panic("attempt to execute unimplemented instruction '%s' "
1186691Stjones1@inf.ed.ac.uk              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
1196691Stjones1@inf.ed.ac.uk              inst2string(machInst));
12010474Sandreas.hansson@arm.com        return std::make_shared<UnimplementedOpcodeFault>();
1216691Stjones1@inf.ed.ac.uk    }
1226691Stjones1@inf.ed.ac.uk
1236691Stjones1@inf.ed.ac.uk    Fault
12412234Sgabeblack@google.com    WarnUnimplemented::execute(ExecContext *xc,
1256691Stjones1@inf.ed.ac.uk                               Trace::InstRecord *traceData) const
1266691Stjones1@inf.ed.ac.uk    {
1276691Stjones1@inf.ed.ac.uk        if (!warned) {
1286691Stjones1@inf.ed.ac.uk            warn("\tinstruction '%s' unimplemented\n", mnemonic);
1296691Stjones1@inf.ed.ac.uk            warned = true;
1306691Stjones1@inf.ed.ac.uk        }
1316691Stjones1@inf.ed.ac.uk
1326691Stjones1@inf.ed.ac.uk        return NoFault;
1336691Stjones1@inf.ed.ac.uk    }
1346691Stjones1@inf.ed.ac.uk}};
1356691Stjones1@inf.ed.ac.uk
1366691Stjones1@inf.ed.ac.uk
1376691Stjones1@inf.ed.ac.ukdef format FailUnimpl() {{
1386691Stjones1@inf.ed.ac.uk    iop = InstObjParams(name, 'FailUnimplemented')
1396691Stjones1@inf.ed.ac.uk    decode_block = BasicDecodeWithMnemonic.subst(iop)
1406691Stjones1@inf.ed.ac.uk}};
1416691Stjones1@inf.ed.ac.uk
1426691Stjones1@inf.ed.ac.ukdef format WarnUnimpl() {{
1436691Stjones1@inf.ed.ac.uk    iop = InstObjParams(name, 'WarnUnimplemented')
1446691Stjones1@inf.ed.ac.uk    decode_block = BasicDecodeWithMnemonic.subst(iop)
1456691Stjones1@inf.ed.ac.uk}};
1466691Stjones1@inf.ed.ac.uk
147