2692590049
--HG-- extra : convert_revision : d4e19afda897bc3797868b40469ce2ec7ec7d251
284 lines
9.4 KiB
C++
284 lines
9.4 KiB
C++
// -*- mode:c++ -*-
|
||
|
||
// Copyright N) 2007 MIPS Technologies, Inc. All Rights Reserved
|
||
|
||
// This software is part of the M5 simulator.
|
||
|
||
// THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING
|
||
// DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
|
||
// TO THESE TERMS AND CONDITIONS.
|
||
|
||
// Permission is granted to use, copy, create derivative works and
|
||
// distribute this software and such derivative works for any purpose,
|
||
// so long as (1) the copyright notice above, this grant of permission,
|
||
// and the disclaimer below appear in all copies and derivative works
|
||
// made, (2) the copyright notice above is augmented as appropriate to
|
||
// reflect the addition of any new copyrightable work in a derivative
|
||
// work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3)
|
||
// the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any
|
||
// advertising or publicity pertaining to the use or distribution of
|
||
// this software without specific, written prior authorization.
|
||
|
||
// THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B MIPS MAKES NO WARRANTIES AND
|
||
// DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
|
||
// OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||
// NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
|
||
// IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
|
||
// INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
|
||
// ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
|
||
// THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
|
||
// IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
|
||
// STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
|
||
// POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
|
||
|
||
//Authors: Korey L. Sewell
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Unimplemented instructions
|
||
//
|
||
|
||
output header {{
|
||
/**
|
||
* Static instruction class for unimplemented instructions that
|
||
* cause simulator termination. Note that these are recognized
|
||
* (legal) instructions that the simulator does not support; the
|
||
* 'Unknown' class is used for unrecognized/illegal instructions.
|
||
* This is a leaf class.
|
||
*/
|
||
class FailUnimplemented : public MipsStaticInst
|
||
{
|
||
public:
|
||
/// Constructor
|
||
FailUnimplemented(const char *_mnemonic, MachInst _machInst)
|
||
: MipsStaticInst(_mnemonic, _machInst, No_OpClass)
|
||
{
|
||
// don't call execute() (which panics) if we're on a
|
||
// speculative path
|
||
flags[IsNonSpeculative] = true;
|
||
}
|
||
|
||
%(BasicExecDeclare)s
|
||
|
||
std::string
|
||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||
};
|
||
class CP0Unimplemented : public MipsStaticInst
|
||
{
|
||
public:
|
||
/// Constructor
|
||
CP0Unimplemented(const char *_mnemonic, MachInst _machInst)
|
||
: MipsStaticInst(_mnemonic, _machInst, No_OpClass)
|
||
{
|
||
// don't call execute() (which panics) if we're on a
|
||
// speculative path
|
||
flags[IsNonSpeculative] = true;
|
||
}
|
||
|
||
%(BasicExecDeclare)s
|
||
|
||
std::string
|
||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||
};
|
||
class CP1Unimplemented : public MipsStaticInst
|
||
{
|
||
public:
|
||
/// Constructor
|
||
CP1Unimplemented(const char *_mnemonic, MachInst _machInst)
|
||
: MipsStaticInst(_mnemonic, _machInst, No_OpClass)
|
||
{
|
||
// don't call execute() (which panics) if we're on a
|
||
// speculative path
|
||
flags[IsNonSpeculative] = true;
|
||
}
|
||
|
||
%(BasicExecDeclare)s
|
||
|
||
std::string
|
||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||
};
|
||
class CP2Unimplemented : public MipsStaticInst
|
||
{
|
||
public:
|
||
/// Constructor
|
||
CP2Unimplemented(const char *_mnemonic, MachInst _machInst)
|
||
: MipsStaticInst(_mnemonic, _machInst, No_OpClass)
|
||
{
|
||
// don't call execute() (which panics) if we're on a
|
||
// speculative path
|
||
flags[IsNonSpeculative] = true;
|
||
}
|
||
|
||
%(BasicExecDeclare)s
|
||
|
||
std::string
|
||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||
};
|
||
|
||
/**
|
||
* Base class for unimplemented instructions that cause a warning
|
||
* to be printed (but do not terminate simulation). This
|
||
* implementation is a little screwy in that it will print a
|
||
* warning for each instance of a particular unimplemented machine
|
||
* instruction, not just for each unimplemented opcode. Should
|
||
* probably make the 'warned' flag a static member of the derived
|
||
* class.
|
||
*/
|
||
class WarnUnimplemented : public MipsStaticInst
|
||
{
|
||
private:
|
||
/// Have we warned on this instruction yet?
|
||
mutable bool warned;
|
||
|
||
public:
|
||
/// Constructor
|
||
WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
|
||
: MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
|
||
{
|
||
// don't call execute() (which panics) if we're on a
|
||
// speculative path
|
||
flags[IsNonSpeculative] = true;
|
||
}
|
||
|
||
%(BasicExecDeclare)s
|
||
|
||
std::string
|
||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||
};
|
||
}};
|
||
|
||
output decoder {{
|
||
std::string
|
||
FailUnimplemented::generateDisassembly(Addr pc,
|
||
const SymbolTable *symtab) const
|
||
{
|
||
return csprintf("%-10s (unimplemented)", mnemonic);
|
||
}
|
||
|
||
std::string
|
||
CP0Unimplemented::generateDisassembly(Addr pc,
|
||
const SymbolTable *symtab) const
|
||
{
|
||
return csprintf("%-10s (unimplemented)", mnemonic);
|
||
}
|
||
|
||
std::string
|
||
CP1Unimplemented::generateDisassembly(Addr pc,
|
||
const SymbolTable *symtab) const
|
||
{
|
||
return csprintf("%-10s (unimplemented)", mnemonic);
|
||
}
|
||
std::string
|
||
CP2Unimplemented::generateDisassembly(Addr pc,
|
||
const SymbolTable *symtab) const
|
||
{
|
||
return csprintf("%-10s (unimplemented)", mnemonic);
|
||
}
|
||
|
||
std::string
|
||
WarnUnimplemented::generateDisassembly(Addr pc,
|
||
const SymbolTable *symtab) const
|
||
{
|
||
return csprintf("%-10s (unimplemented)", mnemonic);
|
||
}
|
||
}};
|
||
|
||
output exec {{
|
||
Fault
|
||
FailUnimplemented::execute(%(CPU_exec_context)s *xc,
|
||
Trace::InstRecord *traceData) const
|
||
{
|
||
panic("attempt to execute unimplemented instruction '%s' "
|
||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||
inst2string(machInst));
|
||
return new UnimplementedOpcodeFault;
|
||
}
|
||
|
||
Fault
|
||
CP0Unimplemented::execute(%(CPU_exec_context)s *xc,
|
||
Trace::InstRecord *traceData) const
|
||
{
|
||
#if FULL_SYSTEM
|
||
if (!isCoprocessorEnabled(xc, 0)) {
|
||
return new CoprocessorUnusableFault(0);
|
||
}
|
||
return new ReservedInstructionFault;
|
||
#else
|
||
panic("attempt to execute unimplemented instruction '%s' "
|
||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||
inst2string(machInst));
|
||
return new UnimplementedOpcodeFault;
|
||
#endif
|
||
}
|
||
|
||
Fault
|
||
CP1Unimplemented::execute(%(CPU_exec_context)s *xc,
|
||
Trace::InstRecord *traceData) const
|
||
{
|
||
#if FULL_SYSTEM
|
||
if (!isCoprocessorEnabled(xc, 1)) {
|
||
return new CoprocessorUnusableFault(1);
|
||
}
|
||
return new ReservedInstructionFault;
|
||
#else
|
||
panic("attempt to execute unimplemented instruction '%s' "
|
||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||
inst2string(machInst));
|
||
return new UnimplementedOpcodeFault;
|
||
#endif
|
||
}
|
||
Fault
|
||
CP2Unimplemented::execute(%(CPU_exec_context)s *xc,
|
||
Trace::InstRecord *traceData) const
|
||
{
|
||
#if FULL_SYSTEM
|
||
if (!isCoprocessorEnabled(xc, 2)) {
|
||
return new CoprocessorUnusableFault(2);
|
||
}
|
||
return new ReservedInstructionFault;
|
||
#else
|
||
panic("attempt to execute unimplemented instruction '%s' "
|
||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||
inst2string(machInst));
|
||
return new UnimplementedOpcodeFault;
|
||
#endif
|
||
}
|
||
|
||
Fault
|
||
WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
|
||
Trace::InstRecord *traceData) const
|
||
{
|
||
if (!warned) {
|
||
warn("\tinstruction '%s' unimplemented\n", mnemonic);
|
||
warned = true;
|
||
}
|
||
|
||
return NoFault;
|
||
}
|
||
}};
|
||
|
||
|
||
def format FailUnimpl() {{
|
||
iop = InstObjParams(name, 'FailUnimplemented')
|
||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||
|
||
}};
|
||
def format CP0Unimpl() {{
|
||
iop = InstObjParams(name, 'CP0Unimplemented')
|
||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||
}};
|
||
def format CP1Unimpl() {{
|
||
iop = InstObjParams(name, 'CP1Unimplemented')
|
||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||
}};
|
||
def format CP2Unimpl() {{
|
||
iop = InstObjParams(name, 'CP2Unimplemented')
|
||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||
}};
|
||
def format WarnUnimpl() {{
|
||
iop = InstObjParams(name, 'WarnUnimplemented')
|
||
decode_block = BasicDecodeWithMnemonic.subst(iop)
|
||
}};
|
||
|