unimp.isa revision 5268:5bfc53fe60e7
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 MIPS Technologies, Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Korey Sewell
30
31////////////////////////////////////////////////////////////////////
32//
33// Unimplemented instructions
34//
35
36output header {{
37    /**
38     * Static instruction class for unimplemented instructions that
39     * cause simulator termination.  Note that these are recognized
40     * (legal) instructions that the simulator does not support; the
41     * 'Unknown' class is used for unrecognized/illegal instructions.
42     * This is a leaf class.
43     */
44    class FailUnimplemented : public MipsStaticInst
45    {
46      public:
47        /// Constructor
48        FailUnimplemented(const char *_mnemonic, MachInst _machInst)
49            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
50        {
51            // don't call execute() (which panics) if we're on a
52            // speculative path
53            flags[IsNonSpeculative] = true;
54        }
55
56        %(BasicExecDeclare)s
57
58        std::string
59        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
60    };
61    class CP0Unimplemented : public MipsStaticInst
62    {
63      public:
64        /// Constructor
65        CP0Unimplemented(const char *_mnemonic, MachInst _machInst)
66            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
67        {
68            // don't call execute() (which panics) if we're on a
69            // speculative path
70            flags[IsNonSpeculative] = true;
71        }
72
73        %(BasicExecDeclare)s
74
75        std::string
76        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
77    };
78    class CP1Unimplemented : public MipsStaticInst
79    {
80      public:
81        /// Constructor
82        CP1Unimplemented(const char *_mnemonic, MachInst _machInst)
83            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
84        {
85            // don't call execute() (which panics) if we're on a
86            // speculative path
87            flags[IsNonSpeculative] = true;
88        }
89
90        %(BasicExecDeclare)s
91
92        std::string
93        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
94    };
95    class CP2Unimplemented : public MipsStaticInst
96    {
97      public:
98        /// Constructor
99        CP2Unimplemented(const char *_mnemonic, MachInst _machInst)
100            : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
101        {
102            // don't call execute() (which panics) if we're on a
103            // speculative path
104            flags[IsNonSpeculative] = true;
105        }
106
107        %(BasicExecDeclare)s
108
109        std::string
110        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
111    };
112
113    /**
114     * Base class for unimplemented instructions that cause a warning
115     * to be printed (but do not terminate simulation).  This
116     * implementation is a little screwy in that it will print a
117     * warning for each instance of a particular unimplemented machine
118     * instruction, not just for each unimplemented opcode.  Should
119     * probably make the 'warned' flag a static member of the derived
120     * class.
121     */
122    class WarnUnimplemented : public MipsStaticInst
123    {
124      private:
125        /// Have we warned on this instruction yet?
126        mutable bool warned;
127
128      public:
129        /// Constructor
130        WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
131            : MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
132        {
133            // don't call execute() (which panics) if we're on a
134            // speculative path
135            flags[IsNonSpeculative] = true;
136        }
137
138        %(BasicExecDeclare)s
139
140        std::string
141        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
142    };
143}};
144
145output decoder {{
146    std::string
147    FailUnimplemented::generateDisassembly(Addr pc,
148                                           const SymbolTable *symtab) const
149    {
150        return csprintf("%-10s (unimplemented)", mnemonic);
151    }
152
153    std::string
154    CP0Unimplemented::generateDisassembly(Addr pc,
155                                           const SymbolTable *symtab) const
156    {
157        return csprintf("%-10s (unimplemented)", mnemonic);
158    }
159
160    std::string
161    CP1Unimplemented::generateDisassembly(Addr pc,
162                                           const SymbolTable *symtab) const
163    {
164        return csprintf("%-10s (unimplemented)", mnemonic);
165    }
166    std::string
167    CP2Unimplemented::generateDisassembly(Addr pc,
168                                           const SymbolTable *symtab) const
169    {
170        return csprintf("%-10s (unimplemented)", mnemonic);
171    }
172
173    std::string
174    WarnUnimplemented::generateDisassembly(Addr pc,
175                                           const SymbolTable *symtab) const
176    {
177        return csprintf("%-10s (unimplemented)", mnemonic);
178    }
179}};
180
181output exec {{
182    Fault
183    FailUnimplemented::execute(%(CPU_exec_context)s *xc,
184                               Trace::InstRecord *traceData) const
185    {
186        panic("attempt to execute unimplemented instruction '%s' "
187              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
188              inst2string(machInst));
189        return new UnimplementedOpcodeFault;
190    }
191
192    Fault
193    CP0Unimplemented::execute(%(CPU_exec_context)s *xc,
194                               Trace::InstRecord *traceData) const
195    {
196#if  FULL_SYSTEM
197      if (!isCoprocessorEnabled(xc, 0)) {
198        return new CoprocessorUnusableFault(0);
199      }
200      return new ReservedInstructionFault;
201#else
202        panic("attempt to execute unimplemented instruction '%s' "
203              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
204              inst2string(machInst));
205        return new UnimplementedOpcodeFault;
206#endif
207    }
208
209    Fault
210    CP1Unimplemented::execute(%(CPU_exec_context)s *xc,
211                               Trace::InstRecord *traceData) const
212    {
213#if  FULL_SYSTEM
214      if (!isCoprocessorEnabled(xc, 1)) {
215        return new CoprocessorUnusableFault(1);
216      }
217      return new ReservedInstructionFault;
218#else
219        panic("attempt to execute unimplemented instruction '%s' "
220              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
221              inst2string(machInst));
222        return new UnimplementedOpcodeFault;
223#endif
224    }
225    Fault
226    CP2Unimplemented::execute(%(CPU_exec_context)s *xc,
227                               Trace::InstRecord *traceData) const
228    {
229#if  FULL_SYSTEM
230      if (!isCoprocessorEnabled(xc, 2)) {
231        return new CoprocessorUnusableFault(2);
232      }
233      return new ReservedInstructionFault;
234#else
235        panic("attempt to execute unimplemented instruction '%s' "
236              "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
237              inst2string(machInst));
238        return new UnimplementedOpcodeFault;
239#endif
240    }
241
242    Fault
243    WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
244                               Trace::InstRecord *traceData) const
245    {
246        if (!warned) {
247            warn("\tinstruction '%s' unimplemented\n", mnemonic);
248            warned = true;
249        }
250
251        return NoFault;
252    }
253}};
254
255
256def format FailUnimpl() {{
257    iop = InstObjParams(name, 'FailUnimplemented')
258    decode_block = BasicDecodeWithMnemonic.subst(iop)
259
260}};
261def format CP0Unimpl() {{
262    iop = InstObjParams(name, 'CP0Unimplemented')
263    decode_block = BasicDecodeWithMnemonic.subst(iop)
264}};
265def format CP1Unimpl() {{
266    iop = InstObjParams(name, 'CP1Unimplemented')
267    decode_block = BasicDecodeWithMnemonic.subst(iop)
268}};
269def format CP2Unimpl() {{
270    iop = InstObjParams(name, 'CP2Unimplemented')
271    decode_block = BasicDecodeWithMnemonic.subst(iop)
272}};
273def format WarnUnimpl() {{
274    iop = InstObjParams(name, 'WarnUnimplemented')
275    decode_block = BasicDecodeWithMnemonic.subst(iop)
276}};
277
278