+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
-// Base class for sparc instructions, and some support functions
+// Base class for MIPS instructions, and some support functions
//
+//Outputs to decoder.hh
output header {{
/**
* Base class for all SPARC static instructions.
*/
- class SparcStaticInst : public StaticInst<SPARCISA>
+ class MipsStaticInst : public StaticInst<MIPSISA>
{
protected:
// Constructor.
- SparcStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+ MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
: StaticInst<SPARCISA>(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
- bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition);
}};
+//Ouputs to decoder.cc
output decoder {{
- std::string SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
return ss.str();
}
- bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition)
- {
- switch(condition)
- {
- case 0b1000: return true;
- case 0b0000: return false;
- case 0b1001: return !codes.z;
- case 0b0001: return codes.z;
- case 0b1010: return !(codes.z | (codes.n ^ codes.v));
- case 0b0010: return codes.z | (codes.n ^ codes.v);
- case 0b1011: return !(codes.n ^ codes.v);
- case 0b0011: return (codes.n ^ codes.v);
- case 0b1100: return !(codes.c | codes.z);
- case 0b0100: return (codes.c | codes.z);
- case 0b1101: return !codes.c;
- case 0b0101: return codes.c;
- case 0b1110: return !codes.n;
- case 0b0110: return codes.n;
- case 0b1111: return !codes.v;
- case 0b0111: return codes.v;
- }
- }
}};
-// -*- mode:c++ -*-
+e// -*- mode:c++ -*-
-// Copyright (c) 2003-2005 The Regents of The University of Michigan
-// All rights reserved.
+////////////////////////////////////////////////////////////////////
//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met: redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer;
-// redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution;
-// neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
+// Control transfer instructions
//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
output header {{
* where the disassembly string includes the target address (which
* may depend on the PC and/or symbol table).
*/
- class PCDependentDisassembly : public AlphaStaticInst
+ class PCDependentDisassembly : public MipsStaticInst
{
protected:
/// Cached program counter from last disassembly
mutable Addr cachedPC;
+
/// Cached symbol table pointer from last disassembly
mutable const SymbolTable *cachedSymtab;
/// Constructor
PCDependentDisassembly(const char *mnem, MachInst _machInst,
OpClass __opClass)
- : AlphaStaticInst(mnem, _machInst, __opClass),
+ : MipsStaticInst(mnem, _machInst, __opClass),
cachedPC(0), cachedSymtab(0)
{
}
class Branch : public PCDependentDisassembly
{
protected:
- /// Displacement to target address (signed).
- int32_t disp;
+ /// target address (signed) Displacement .
+ int32_t targetOffset;
/// Constructor.
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP << 2)
+ targetOffset(OFFSET << 2)
+ {
+ }
+
+ Addr branchTarget(Addr branchPC) const;
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for branches (PC-relative control transfers),
+ * conditional or unconditional.
+ */
+ class BranchLikely : public PCDependentDisassembly
+ {
+ protected:
+ /// target address (signed) Displacement .
+ int32_t targetOffset;
+
+ /// Constructor.
+ Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ targetOffset(OFFSET << 2)
{
}
/**
* Base class for jumps (register-indirect control transfers). In
- * the Alpha ISA, these are always unconditional.
+ * the Mips ISA, these are always unconditional.
*/
class Jump : public PCDependentDisassembly
{
/// Constructor
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP)
+ disp(OFFSET)
{
}
}};
def template JumpOrBranchDecode {{
- return (RA == 31)
- ? (StaticInst<AlphaISA> *)new %(class_name)s(machInst)
- : (StaticInst<AlphaISA> *)new %(class_name)sAndLink(machInst);
+ return (RD == 0)
+ ? (StaticInst<MipsISA> *)new %(class_name)s(machInst)
+ : (StaticInst<MipsISA> *)new %(class_name)sAndLink(machInst);
}};
-def format CondBranch(code) {{
+def format Branch(code) {{
code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
exec_output = BasicExecute.subst(iop)
}};
-let {{
-def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
- # Declare basic control transfer w/o link (i.e. link reg is R31)
- nolink_code = 'NPC = %s;\n' % npc_expr
- nolink_iop = InstObjParams(name, Name, base_class,
- CodeBlock(nolink_code), flags)
- header_output = BasicDeclare.subst(nolink_iop)
- decoder_output = BasicConstructor.subst(nolink_iop)
- exec_output = BasicExecute.subst(nolink_iop)
-
- # Generate declaration of '*AndLink' version, append to decls
- link_code = 'Ra = NPC & ~3;\n' + nolink_code
- link_iop = InstObjParams(name, Name + 'AndLink', base_class,
- CodeBlock(link_code), flags)
- header_output += BasicDeclare.subst(link_iop)
- decoder_output += BasicConstructor.subst(link_iop)
- exec_output += BasicExecute.subst(link_iop)
-
- # need to use link_iop for the decode template since it is expecting
- # the shorter version of class_name (w/o "AndLink")
-
- return (header_output, decoder_output,
- JumpOrBranchDecode.subst(nolink_iop), exec_output)
+
+def format BranchLikely(code) {{
+ code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
+ iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
+ ('IsDirectControl', 'IsCondControl'))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
+
def format UncondBranch(*flags) {{
flags += ('IsUncondControl', 'IsDirectControl')
(header_output, decoder_output, decode_block, exec_output) = \
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
+//Outputs to decoder.hh
output header {{
/**
* Base class for integer operations.
protected:
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
uint16_t imm;
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM)
{
}
}};
+//Outputs to decoder.cc
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
}
}};
-// Primary format for integer operate instructions:
+
+// integer & FP operate instructions use Rd as dest, so check for
+// Rd == 0 to detect nops
+def template OperateNopCheckDecode {{
+ {
+ MipsStaticInst *i = new %(class_name)s(machInst);
+ if (RD == 0) {
+ i = makeNop(i);
+ }
+ return i;
+ }
+}};
+
+//Used by decoder.isa
def format IntOp(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
# Figure out if we are creating a IntImmOp or a IntOp
+ # by looking at the instruction name
+ iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
strlen = len(name)
if name[strlen-1] == 'i' or name[strlen-2:] == 'iu':
- iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
- else:
- iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)