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:
parent
7b42d61f13
commit
2d04f18674
2 changed files with 170 additions and 1 deletions
|
@ -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))
|
||||
}};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue