Gives separate methods for initiating and completing a memory access, which will be helpful for the merged memory model.

arch/alpha/isa/mem.isa:
    Include methods that allow a memory operation to be split between the part that initiates the access, and the part that completes the access.  In these functions the Mem variable is explicitly declared; in the default execute functions, the Mem variable is still handled through %(op_decl)s.
arch/isa_parser.py:
    Include recording the type of the memory access variable so that it can be used if it needs to be explicitly declared in a template.

    Have memory operands consider themselves neither a source nor a destination to avoid including themselves on the op_src_decl list or the op_dest_decl list.

    Record op_src_decl and op_dest_decl lists to allow for declaring only source or destination operands.  This is needed for the split memory access methods.

--HG--
extra : convert_revision : f674f7a2f747ae40ba8c3a0933b0337c87ee0b6c
This commit is contained in:
Kevin Lim 2006-02-15 13:05:21 -05:00
parent 7b42d61f13
commit 2d04f18674
2 changed files with 170 additions and 1 deletions

View file

@ -164,9 +164,24 @@ def template LoadStoreDeclare {{
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template InitiateAccDeclare {{
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template CompleteAccDeclare {{
Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template LoadStoreConstructor {{
/** TODO: change op_class to AddrGenOp or something (requires
* creating new member of OpClass enum in op_class.hh, updating
@ -267,6 +282,54 @@ def template LoadExecute {{
}};
def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
%(mem_acc_type)s Mem = 0;
%(fp_enable_check)s;
%(op_src_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == No_Fault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
}
return fault;
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = No_Fault;
%(mem_acc_type)s Mem = 0;
%(fp_enable_check)s;
%(op_dest_decl)s;
memcpy(&Mem, data, sizeof(Mem));
if (fault == No_Fault) {
%(memacc_code)s;
}
if (fault == No_Fault) {
%(op_wb)s;
}
return fault;
}
}};
def template StoreMemAccExecute {{
Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
@ -339,6 +402,60 @@ def template StoreExecute {{
}
}};
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
uint64_t write_result = 0;
%(mem_acc_type)s Mem = 0;
%(fp_enable_check)s;
%(op_src_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == No_Fault) {
%(memacc_code)s;
}
if (fault == No_Fault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
memAccessFlags, &write_result);
if (traceData) { traceData->setData(Mem); }
}
return fault;
}
}};
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = No_Fault;
uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_dest_decl)s;
memcpy(&write_result, data, sizeof(write_result));
if (fault == No_Fault) {
%(postacc_code)s;
}
if (fault == No_Fault) {
%(op_wb)s;
}
return fault;
}
}};
def template MiscMemAccExecute {{
Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
@ -380,6 +497,36 @@ def template MiscExecute {{
}
}};
def template MiscInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == No_Fault) {
%(memacc_code)s;
}
return No_Fault;
}
}};
def template MiscCompleteAcc {{
Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return No_Fault;
}
}};
// load instructions use Ra as dest, so check for
// Ra == 31 to detect nops
def template LoadNopCheckDecode {{
@ -455,13 +602,17 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
# select templates
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)
return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
decode_template.subst(iop),
EACompExecute.subst(ea_iop)
+ memAccExecTemplate.subst(memacc_iop)
+ fullExecTemplate.subst(iop))
+ fullExecTemplate.subst(iop)
+ initiateAccTemplate.subst(iop)
+ completeAccTemplate.subst(iop))
}};

View file

@ -1138,6 +1138,7 @@ class Operand(object):
# template must be careful not to use it if it doesn't apply.
if self.isMem():
self.mem_acc_size = self.makeAccSize()
self.mem_acc_type = self.ctype
# Finalize additional fields (primarily code fields). This step
# is done separately since some of these fields may depend on the
@ -1148,15 +1149,23 @@ class Operand(object):
self.constructor = self.makeConstructor()
self.op_decl = self.makeDecl()
if self.isMem():
self.is_src = ''
self.is_dest = ''
if self.is_src:
self.op_rd = self.makeRead()
self.op_src_decl = self.makeDecl()
else:
self.op_rd = ''
self.op_src_decl = ''
if self.is_dest:
self.op_wb = self.makeWrite()
self.op_dest_decl = self.makeDecl()
else:
self.op_wb = ''
self.op_dest_decl = ''
def isMem(self):
return 0
@ -1589,6 +1598,14 @@ class CodeBlock:
self.op_decl = self.operands.concatAttrStrings('op_decl')
is_src = lambda op: op.is_src
is_dest = lambda op: op.is_dest
self.op_src_decl = \
self.operands.concatSomeAttrStrings(is_src, 'op_src_decl')
self.op_dest_decl = \
self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
self.op_rd = self.operands.concatAttrStrings('op_rd')
self.op_wb = self.operands.concatAttrStrings('op_wb')
@ -1596,6 +1613,7 @@ class CodeBlock:
if self.operands.memOperand:
self.mem_acc_size = self.operands.memOperand.mem_acc_size
self.mem_acc_type = self.operands.memOperand.mem_acc_type
# Make a basic guess on the operand class (function unit type).
# These are good enough for most cases, and will be overridden