2006-02-16 08:51:04 +01:00
|
|
|
// -*- mode:c++ -*-
|
|
|
|
|
2006-06-15 07:00:15 +02:00
|
|
|
// Copyright (c) 2006 The Regents of The University of Michigan
|
2006-06-10 00:19:08 +02:00
|
|
|
// 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
|
|
|
|
// Korey Sewell
|
|
|
|
|
2006-02-16 08:51:04 +01:00
|
|
|
let {{
|
2006-02-20 20:30:23 +01:00
|
|
|
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
|
|
|
postacc_code = '', base_class = 'Memory',
|
|
|
|
decode_template = BasicDecode, exec_template_base = ''):
|
|
|
|
# Make sure flags are in lists (convert to lists if not).
|
|
|
|
mem_flags = makeList(mem_flags)
|
|
|
|
inst_flags = makeList(inst_flags)
|
|
|
|
|
|
|
|
# add hook to get effective addresses into execution trace output.
|
|
|
|
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
|
|
|
|
|
|
|
# Some CPU models execute the memory operation as an atomic unit,
|
|
|
|
# while others want to separate them into an effective address
|
|
|
|
# computation and a memory access operation. As a result, we need
|
|
|
|
# to generate three StaticInst objects. Note that the latter two
|
|
|
|
# are nested inside the larger "atomic" one.
|
|
|
|
|
2006-12-18 04:27:50 +01:00
|
|
|
# Generate InstObjParams for each of the three objects. Note that
|
|
|
|
# they differ only in the set of code objects contained (which in
|
|
|
|
# turn affects the object's overall operand list).
|
|
|
|
iop = InstObjParams(name, Name, base_class,
|
|
|
|
{ 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
|
|
|
|
inst_flags)
|
|
|
|
ea_iop = InstObjParams(name, Name, base_class,
|
|
|
|
{ 'ea_code':ea_code },
|
|
|
|
inst_flags)
|
|
|
|
memacc_iop = InstObjParams(name, Name, base_class,
|
|
|
|
{ 'memacc_code':memacc_code, 'postacc_code':postacc_code },
|
|
|
|
inst_flags)
|
2006-02-20 20:30:23 +01:00
|
|
|
|
|
|
|
if mem_flags:
|
|
|
|
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
|
|
|
iop.constructor += s
|
|
|
|
memacc_iop.constructor += s
|
|
|
|
|
|
|
|
# select templates
|
2006-07-23 19:39:42 +02:00
|
|
|
|
2007-02-13 17:09:09 +01:00
|
|
|
# The InitiateAcc template is the same for StoreCond templates as the
|
|
|
|
# corresponding Store template..
|
2006-07-23 19:39:42 +02:00
|
|
|
StoreCondInitiateAcc = StoreInitiateAcc
|
|
|
|
|
2006-02-20 20:30:23 +01:00
|
|
|
memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
|
|
|
|
fullExecTemplate = eval(exec_template_base + 'Execute')
|
|
|
|
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
|
|
|
|
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
|
|
|
|
|
|
|
# (header_output, decoder_output, decode_block, exec_output)
|
2006-12-18 04:27:50 +01:00
|
|
|
return (LoadStoreDeclare.subst(iop),
|
|
|
|
EACompConstructor.subst(ea_iop)
|
|
|
|
+ MemAccConstructor.subst(memacc_iop)
|
|
|
|
+ LoadStoreConstructor.subst(iop),
|
2006-02-20 20:30:23 +01:00
|
|
|
decode_template.subst(iop),
|
|
|
|
EACompExecute.subst(ea_iop)
|
|
|
|
+ memAccExecTemplate.subst(memacc_iop)
|
|
|
|
+ fullExecTemplate.subst(iop)
|
2006-12-18 04:27:50 +01:00
|
|
|
+ initiateAccTemplate.subst(iop)
|
|
|
|
+ completeAccTemplate.subst(iop))
|
2006-02-16 08:51:04 +01:00
|
|
|
}};
|
2006-12-18 04:27:50 +01:00
|
|
|
|
|
|
|
|
2006-06-09 09:57:25 +02:00
|
|
|
output header {{
|
|
|
|
std::string inst2string(MachInst machInst);
|
|
|
|
}};
|
|
|
|
|
|
|
|
output decoder {{
|
|
|
|
|
|
|
|
std::string inst2string(MachInst machInst)
|
|
|
|
{
|
2006-08-15 11:07:15 +02:00
|
|
|
std::string str = "";
|
2006-06-09 09:57:25 +02:00
|
|
|
uint32_t mask = 0x80000000;
|
|
|
|
|
|
|
|
for(int i=0; i < 32; i++) {
|
|
|
|
if ((machInst & mask) == 0) {
|
|
|
|
str += "0";
|
|
|
|
} else {
|
|
|
|
str += "1";
|
|
|
|
}
|
2006-02-20 20:30:23 +01:00
|
|
|
|
2006-06-09 09:57:25 +02:00
|
|
|
mask = mask >> 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
}};
|
2006-02-20 07:49:16 +01:00
|
|
|
output exec {{
|
|
|
|
|
2006-04-12 09:44:45 +02:00
|
|
|
using namespace MipsISA;
|
|
|
|
|
2006-02-20 07:49:16 +01:00
|
|
|
/// CLEAR ALL CPU INST/EXE HAZARDS
|
|
|
|
inline void
|
|
|
|
clear_exe_inst_hazards()
|
|
|
|
{
|
|
|
|
//CODE HERE
|
|
|
|
}
|
2006-03-08 08:05:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
/// Check "FP enabled" machine status bit. Called when executing any FP
|
|
|
|
/// instruction in full-system mode.
|
|
|
|
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
|
|
|
|
/// if not. Non-full-system mode: always returns NoFault.
|
|
|
|
#if FULL_SYSTEM
|
|
|
|
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
|
|
|
{
|
|
|
|
Fault fault = NoFault; // dummy... this ipr access should not fault
|
|
|
|
if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) {
|
|
|
|
fault = FloatEnableFault;
|
|
|
|
}
|
|
|
|
return fault;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
|
|
|
|
{
|
|
|
|
return NoFault;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2006-06-09 09:57:25 +02:00
|
|
|
|
2006-02-22 09:33:35 +01:00
|
|
|
}};
|
2006-03-08 08:05:38 +01:00
|
|
|
|
|
|
|
|