1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 The Hewlett-Packard Development Company
4// All rights reserved.
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39
40////////////////////////////////////////////////////////////////////
41//
42// Unimplemented instructions
43//
44
45output header {{
46    /**
47     * Static instruction class for unimplemented instructions that
48     * cause simulator termination.  Note that these are recognized
49     * (legal) instructions that the simulator does not support; the
50     * 'Unknown' class is used for unrecognized/illegal instructions.
51     * This is a leaf class.
52     */
53    class FailUnimplemented : public X86ISA::X86StaticInst
54    {
55      public:
56        /// Constructor
57        FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
58            : X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass)
59        {
60            // don't call execute() (which panics) if we're on a
61            // speculative path
62            flags[IsNonSpeculative] = true;
63        }
64
65        Fault execute(ExecContext *, Trace::InstRecord *) const;
66
67        std::string
68        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
69    };
70
71    /**
72     * Base class for unimplemented instructions that cause a warning
73     * to be printed (but do not terminate simulation).  This
74     * implementation is a little screwy in that it will print a
75     * warning for each instance of a particular unimplemented machine
76     * instruction, not just for each unimplemented opcode.  Should
77     * probably make the 'warned' flag a static member of the derived
78     * class.
79     */
80    class WarnUnimplemented : public X86ISA::X86StaticInst
81    {
82      private:
83        /// Have we warned on this instruction yet?
84        mutable bool warned;
85
86      public:
87        /// Constructor
88        WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
89            : X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
90        {
91            // don't call execute() (which panics) if we're on a
92            // speculative path
93            flags[IsNonSpeculative] = true;
94        }
95
96        Fault execute(ExecContext *, Trace::InstRecord *) const;
97
98        std::string
99        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
100    };
101}};
102
103output decoder {{
104    std::string
105    FailUnimplemented::generateDisassembly(Addr pc,
106                                           const SymbolTable *symtab) const
107    {
108        return csprintf("%-10s (unimplemented)", mnemonic);
109    }
110
111    std::string
112    WarnUnimplemented::generateDisassembly(Addr pc,
113                                           const SymbolTable *symtab) const
114    {
115#ifdef SS_COMPATIBLE_DISASSEMBLY
116        return csprintf("%-10s", mnemonic);
117#else
118        return csprintf("%-10s (unimplemented)", mnemonic);
119#endif
120    }
121}};
122
123output exec {{
124    Fault
125    FailUnimplemented::execute(ExecContext *xc,
126                               Trace::InstRecord *traceData) const
127    {
128        panic("attempt to execute unimplemented instruction '%s' %s",
129                mnemonic, machInst);
130        return NoFault;
131    }
132
133    Fault
134    WarnUnimplemented::execute(ExecContext *xc,
135                               Trace::InstRecord *traceData) const
136    {
137        if (!warned) {
138            warn("instruction '%s' unimplemented\n", mnemonic);
139            warned = true;
140        }
141
142        return NoFault;
143    }
144}};
145
146
147def format FailUnimpl() {{
148    iop = InstObjParams(name, 'FailUnimplemented')
149    decode_block = BasicDecodeWithMnemonic.subst(iop)
150}};
151
152def format WarnUnimpl() {{
153    iop = InstObjParams(name, 'WarnUnimplemented')
154    decode_block = BasicDecodeWithMnemonic.subst(iop)
155}};
156
157