Adding gem5 source to svn.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
274
simulators/gem5/src/arch/alpha/isa/branch.isa
Normal file
274
simulators/gem5/src/arch/alpha/isa/branch.isa
Normal file
@ -0,0 +1,274 @@
|
||||
// -*- 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.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Authors: Steve Reinhardt
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Control transfer instructions
|
||||
//
|
||||
|
||||
output header {{
|
||||
|
||||
/**
|
||||
* Base class for instructions whose disassembly is not purely a
|
||||
* function of the machine instruction (i.e., it depends on the
|
||||
* PC). This class overrides the disassemble() method to check
|
||||
* the PC and symbol table values before re-using a cached
|
||||
* disassembly string. This is necessary for branches and jumps,
|
||||
* where the disassembly string includes the target address (which
|
||||
* may depend on the PC and/or symbol table).
|
||||
*/
|
||||
class PCDependentDisassembly : public AlphaStaticInst
|
||||
{
|
||||
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, ExtMachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: AlphaStaticInst(mnem, _machInst, __opClass),
|
||||
cachedPC(0), cachedSymtab(0)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &
|
||||
disassemble(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for branches (PC-relative control transfers),
|
||||
* conditional or unconditional.
|
||||
*/
|
||||
class Branch : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
/// Displacement to target address (signed).
|
||||
int32_t disp;
|
||||
|
||||
/// Constructor.
|
||||
Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(BRDISP << 2)
|
||||
{
|
||||
}
|
||||
|
||||
AlphaISA::PCState branchTarget(const AlphaISA::PCState &branchPC) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for jumps (register-indirect control transfers). In
|
||||
* the Alpha ISA, these are always unconditional.
|
||||
*/
|
||||
class Jump : public PCDependentDisassembly
|
||||
{
|
||||
protected:
|
||||
|
||||
/// Displacement to target address (signed).
|
||||
int32_t disp;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Jump(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
|
||||
: PCDependentDisassembly(mnem, _machInst, __opClass),
|
||||
disp(BRDISP)
|
||||
{
|
||||
}
|
||||
|
||||
AlphaISA::PCState branchTarget(ThreadContext *tc) const;
|
||||
|
||||
std::string
|
||||
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
AlphaISA::PCState
|
||||
Branch::branchTarget(const AlphaISA::PCState &branchPC) const
|
||||
{
|
||||
return branchPC.pc() + 4 + disp;
|
||||
}
|
||||
|
||||
AlphaISA::PCState
|
||||
Jump::branchTarget(ThreadContext *tc) const
|
||||
{
|
||||
PCState pc = tc->pcState();
|
||||
uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
|
||||
pc.set((Rb & ~3) | (pc.pc() & 1));
|
||||
return pc;
|
||||
}
|
||||
|
||||
const std::string &
|
||||
PCDependentDisassembly::disassemble(Addr pc,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
if (!cachedDisassembly ||
|
||||
pc != cachedPC || symtab != cachedSymtab)
|
||||
{
|
||||
if (cachedDisassembly)
|
||||
delete cachedDisassembly;
|
||||
|
||||
cachedDisassembly =
|
||||
new std::string(generateDisassembly(pc, symtab));
|
||||
cachedPC = pc;
|
||||
cachedSymtab = symtab;
|
||||
}
|
||||
|
||||
return *cachedDisassembly;
|
||||
}
|
||||
|
||||
std::string
|
||||
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
// There's only one register arg (RA), but it could be
|
||||
// either a source (the condition for conditional
|
||||
// branches) or a destination (the link reg for
|
||||
// unconditional branches)
|
||||
if (_numSrcRegs > 0) {
|
||||
printReg(ss, _srcRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
else if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
if (_numSrcRegs == 0 && _numDestRegs == 0) {
|
||||
printReg(ss, 31);
|
||||
ss << ",";
|
||||
}
|
||||
#endif
|
||||
|
||||
Addr target = pc + 4 + disp;
|
||||
|
||||
std::string str;
|
||||
if (symtab && symtab->findSymbol(target, str))
|
||||
ss << str;
|
||||
else
|
||||
ccprintf(ss, "0x%x", target);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ccprintf(ss, "%-10s ", mnemonic);
|
||||
|
||||
#ifdef SS_COMPATIBLE_DISASSEMBLY
|
||||
if (_numDestRegs == 0) {
|
||||
printReg(ss, 31);
|
||||
ss << ",";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_numDestRegs > 0) {
|
||||
printReg(ss, _destRegIdx[0]);
|
||||
ss << ",";
|
||||
}
|
||||
|
||||
ccprintf(ss, "(r%d)", RB);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def template JumpOrBranchDecode {{
|
||||
return (RA == 31)
|
||||
? (StaticInst *)new %(class_name)s(machInst)
|
||||
: (StaticInst *)new %(class_name)sAndLink(machInst);
|
||||
}};
|
||||
|
||||
def format CondBranch(code) {{
|
||||
code = '''
|
||||
bool cond;
|
||||
%(code)s;
|
||||
if (cond)
|
||||
NPC = NPC + disp;
|
||||
else
|
||||
NPC = NPC;
|
||||
''' % { "code" : code }
|
||||
iop = InstObjParams(name, Name, 'Branch', code,
|
||||
('IsDirectControl', 'IsCondControl'))
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
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,
|
||||
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,
|
||||
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 UncondBranch(*flags) {{
|
||||
flags += ('IsUncondControl', 'IsDirectControl')
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags)
|
||||
}};
|
||||
|
||||
def format Jump(*flags) {{
|
||||
flags += ('IsUncondControl', 'IsIndirectControl')
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags)
|
||||
}};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user