// -*- mode:c++ -*-
-// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// (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: Gabe Black
+// Authors: Steve Reinhardt
// Korey Sewell
////////////////////////////////////////////////////////////////////
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: MipsStaticInst(mnem, _machInst, __opClass),
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
- disp(OFFSET)
+ disp(sext<16>(OFFSET))
{
- //If Bit 15 is 1 then Sign Extend
- int32_t temp = disp & 0x00008000;
-
- if (temp > 0) {
- disp |= 0xFFFF0000;
- }
}
std::string
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
const StaticInstPtr &memAccInst() const { return memAccPtr; }
+
+ unsigned memAccFlags() { return memAccessFlags; }
};
+ /**
+ * Base class for a few miscellaneous memory-format insts
+ * that don't interpret the disp field
+ */
+ class MemoryNoDisp : public Memory
+ {
+ protected:
+ /// Constructor
+ MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
+ {
+ }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
}};
std::string
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
+ return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
}
+ std::string
+ MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
+ flags[IsFloating] ? 'f' : 'r',
+ flags[IsFloating] ? FD : RD,
+ RS, RT);
+ }
+
+}};
+
+output exec {{
+ /** return data in cases where there the size of data is only
+ known in the packet
+ */
+ uint64_t getStoreData(%(CPU_exec_context)s *xc, Packet *packet) {
+ switch (packet->getSize())
+ {
+ case 8:
+ return packet->get<uint8_t>();
+
+ case 16:
+ return packet->get<uint16_t>();
+
+ case 32:
+ return packet->get<uint32_t>();
+
+ case 864:
+ return packet->get<uint64_t>();
+
+ default:
+ std::cerr << "bad store data size = " << packet->getSize() << std::endl;
+
+ assert(0);
+ return 0;
+ }
+ }
+
+
}};
def template LoadStoreDeclare {{
{
public:
/// Constructor
- EAComp(MachInst machInst);
+ EAComp(ExtMachInst machInst);
%(BasicExecDeclare)s
};
{
public:
/// Constructor
- MemAcc(MachInst machInst);
+ MemAcc(ExtMachInst machInst);
%(BasicExecDeclare)s
};
public:
/// Constructor.
- %(class_name)s(MachInst machInst);
+ %(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
+
+ %(MemAccSizeDeclare)s
};
}};
def template CompleteAccDeclare {{
- Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
+def template MemAccSizeDeclare {{
+ int memAccSize(%(CPU_exec_context)s *xc);
+}};
-def template LoadStoreConstructor {{
+def template EACompConstructor {{
/** TODO: change op_class to AddrGenOp or something (requires
* creating new member of OpClass enum in op_class.hh, updating
* config files, etc.). */
- inline %(class_name)s::EAComp::EAComp(MachInst machInst)
+ inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
{
- %(ea_constructor)s;
+ %(constructor)s;
}
+}};
+
- inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
+def template MemAccConstructor {{
+ inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
{
- %(memacc_constructor)s;
+ %(constructor)s;
}
+}};
- inline %(class_name)s::%(class_name)s(MachInst machInst)
+
+def template LoadStoreConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
new EAComp(machInst), new MemAcc(machInst))
{
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
- %(code)s;
+ %(ea_code)s;
+ // NOTE: Trace Data is written using execute or completeAcc templates
if (fault == NoFault) {
- %(op_wb)s;
xc->setEA(EA);
}
Addr EA;
Fault fault = NoFault;
- %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
+
EA = xc->getEA();
- if (fault == NoFault) {
- fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
- %(code)s;
- }
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
- if (fault == NoFault) {
- %(op_wb)s;
- }
+ %(memacc_code)s;
+
+ // NOTE: Write back data using execute or completeAcc templates
return fault;
}
}
}};
-
def template LoadCompleteAcc {{
- Fault %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
%(fp_enable_check)s;
%(op_decl)s;
+ %(op_rd)s;
- memcpy(&Mem, data, sizeof(Mem));
+ Mem = pkt->get<typeof(Mem)>();
if (fault == NoFault) {
%(memacc_code)s;
}};
+
+def template LoadStoreMemAccSize {{
+ int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+ {
+ // Return the memory access size in bytes
+ return (%(mem_acc_size)d / 8);
+ }
+}};
+
def template StoreMemAccExecute {{
+ Fault
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ // @NOTE: Need to Call Complete Access to Set Trace Data
+ //if (traceData) { traceData->setData(Mem); }
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondMemAccExecute {{
Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
EA = xc->getEA();
if (fault == NoFault) {
- %(code)s;
+ %(memacc_code)s;
}
if (fault == NoFault) {
}
}};
-
def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
{
Addr EA;
Fault fault = NoFault;
- uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_decl)s;
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
- memAccessFlags, &write_result);
+ memAccessFlags, NULL);
if (traceData) { traceData->setData(Mem); }
}
def template StoreCompleteAcc {{
- Fault %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(Packet *pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_dest_decl)s;
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+
+ if (traceData) { traceData->setData(getStoreData(xc, pkt)); }
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondCompleteAcc {{
+ Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
- uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_dest_decl)s;
- memcpy(&write_result, data, sizeof(write_result));
+ uint64_t write_result = pkt->req->getExtraData();
if (fault == NoFault) {
%(postacc_code)s;
EA = xc->getEA();
if (fault == NoFault) {
- %(code)s;
+ %(memacc_code)s;
}
return NoFault;
def template MiscCompleteAcc {{
- Fault %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
}
}};
-// load instructions use Rt as dest, so check for
-// Rt == 0 to detect nops
-def template LoadNopCheckDecode {{
- {
- MipsStaticInst *i = new %(class_name)s(machInst);
- if (RT == 0) {
- i = makeNop(i);
- }
- return i;
- }
+
+def template MiscMemAccSize {{
+ int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+ {
+ panic("Misc instruction does not support split access method!");
+ return 0;
+ }
}};
def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = LoadNopCheckDecode,
+ decode_template = ImmNopCheckDecode,
exec_template_base = 'Load')
}};
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = LoadNopCheckDecode,
+ decode_template = ImmNopCheckDecode,
exec_template_base = 'Load')
}};
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = LoadNopCheckDecode,
+ decode_template = ImmNopCheckDecode,
exec_template_base = 'Load')
}};
decl_code += '\tbyte_offset ^= 3;\n'
decl_code += '#endif\n'
decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
+ #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = LoadNopCheckDecode,
exec_template_base = 'Store')
}};
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- postacc_code, exec_template_base = 'Store')
+ postacc_code, exec_template_base = 'StoreCond')
}};