summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/isa/base.isa63
-rw-r--r--arch/mips/isa/formats/basic.isa1
-rw-r--r--arch/mips/isa/formats/branch.isa106
-rw-r--r--arch/mips/isa/formats/int.isa29
4 files changed, 135 insertions, 64 deletions
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
new file mode 100644
index 000000000..99fa302c0
--- /dev/null
+++ b/arch/mips/isa/base.isa
@@ -0,0 +1,63 @@
+// -*- mode:c++ -*-
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for MIPS instructions, and some support functions
+//
+
+//Outputs to decoder.hh
+output header {{
+ /**
+ * Base class for all SPARC static instructions.
+ */
+ class MipsStaticInst : public StaticInst<MIPSISA>
+ {
+ protected:
+
+ // Constructor.
+ MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : StaticInst<SPARCISA>(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+}};
+
+//Ouputs to decoder.cc
+output decoder {{
+
+ std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // just print the first two source regs... if there's
+ // a third one, it's a read-modify-write dest (Rc),
+ // e.g. for CMOVxx
+ if(_numSrcRegs > 0)
+ {
+ printReg(ss, _srcRegIdx[0]);
+ }
+ if(_numSrcRegs > 1)
+ {
+ ss << ",";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ // just print the first dest... if there's a second one,
+ // it's generally implicit
+ if(_numDestRegs > 0)
+ {
+ if(_numSrcRegs > 0)
+ ss << ",";
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ return ss.str();
+ }
+
+}};
+
diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa
index fc97c6ffa..24c397685 100644
--- a/arch/mips/isa/formats/basic.isa
+++ b/arch/mips/isa/formats/basic.isa
@@ -1,3 +1,4 @@
+// -*- mode:c++ -*-
// Declarations for execute() methods.
def template BasicExecDeclare {{
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index e9c790c53..45980349d 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -1,30 +1,9 @@
-// -*- 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 {{
@@ -37,18 +16,19 @@ 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)
{
}
@@ -64,13 +44,36 @@ output header {{
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)
{
}
@@ -82,7 +85,7 @@ output header {{
/**
* 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
{
@@ -95,7 +98,7 @@ output header {{
/// Constructor
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP)
+ disp(OFFSET)
{
}
@@ -204,12 +207,12 @@ output decoder {{
}};
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'))
@@ -219,31 +222,18 @@ def format CondBranch(code) {{
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) = \
diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa
index 521f3a130..982992b41 100644
--- a/arch/mips/isa/formats/int.isa
+++ b/arch/mips/isa/formats/int.isa
@@ -1,8 +1,11 @@
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
+//Outputs to decoder.hh
output header {{
/**
* Base class for integer operations.
@@ -12,7 +15,7 @@ output header {{
protected:
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
@@ -26,7 +29,7 @@ output header {{
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)
{
}
@@ -36,6 +39,7 @@ output header {{
}};
+//Outputs to decoder.cc
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
@@ -48,17 +52,30 @@ output decoder {{
}
}};
-// 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)