2006-02-16 08:51:04 +01:00
|
|
|
// -*- mode:c++ -*-
|
|
|
|
|
|
|
|
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,
|
|
|
|
CodeBlock(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,
|
|
|
|
CodeBlock(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)
|
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'
|
|
|
|
|
|
|
|
# generate code block objects
|
|
|
|
ea_cblk = CodeBlock(ea_code)
|
|
|
|
memacc_cblk = CodeBlock(memacc_code)
|
|
|
|
postacc_cblk = CodeBlock(postacc_code)
|
|
|
|
|
|
|
|
# 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.
|
|
|
|
|
|
|
|
# generate InstObjParams for EAComp object
|
|
|
|
ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
|
|
|
|
|
|
|
|
# generate InstObjParams for MemAcc object
|
|
|
|
memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
|
|
|
|
# in the split execution model, the MemAcc portion is responsible
|
|
|
|
# for the post-access code.
|
|
|
|
memacc_iop.postacc_code = postacc_cblk.code
|
|
|
|
|
|
|
|
# generate InstObjParams for InitiateAcc, CompleteAcc object
|
|
|
|
# The code used depends on the template being used
|
|
|
|
if (exec_template_base == 'Load'):
|
|
|
|
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
|
|
|
|
completeacc_cblk = CodeBlock(memacc_code + postacc_code)
|
|
|
|
elif (exec_template_base == 'Store'):
|
|
|
|
initiateacc_cblk = CodeBlock(ea_code + memacc_code)
|
|
|
|
completeacc_cblk = CodeBlock(postacc_code)
|
|
|
|
else:
|
|
|
|
initiateacc_cblk = ''
|
|
|
|
completeacc_cblk = ''
|
|
|
|
|
|
|
|
initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
|
|
|
|
inst_flags)
|
|
|
|
|
|
|
|
completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
|
|
|
|
inst_flags)
|
|
|
|
|
|
|
|
if (exec_template_base == 'Load'):
|
|
|
|
initiateacc_iop.ea_code = ea_cblk.code
|
|
|
|
initiateacc_iop.memacc_code = memacc_cblk.code
|
|
|
|
completeacc_iop.memacc_code = memacc_cblk.code
|
|
|
|
completeacc_iop.postacc_code = postacc_cblk.code
|
|
|
|
elif (exec_template_base == 'Store'):
|
|
|
|
initiateacc_iop.ea_code = ea_cblk.code
|
|
|
|
initiateacc_iop.memacc_code = memacc_cblk.code
|
|
|
|
completeacc_iop.postacc_code = postacc_cblk.code
|
|
|
|
|
|
|
|
# generate InstObjParams for unified execution
|
|
|
|
cblk = CodeBlock(ea_code + memacc_code + postacc_code)
|
|
|
|
iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
|
|
|
|
|
|
|
|
iop.ea_constructor = ea_cblk.constructor
|
|
|
|
iop.ea_code = ea_cblk.code
|
|
|
|
iop.memacc_constructor = memacc_cblk.constructor
|
|
|
|
iop.memacc_code = memacc_cblk.code
|
|
|
|
iop.postacc_code = postacc_cblk.code
|
|
|
|
|
|
|
|
if mem_flags:
|
|
|
|
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
|
|
|
iop.constructor += s
|
|
|
|
memacc_iop.constructor += s
|
|
|
|
|
|
|
|
# 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)
|
|
|
|
+ initiateAccTemplate.subst(initiateacc_iop)
|
|
|
|
+ completeAccTemplate.subst(completeacc_iop))
|
2006-02-16 08:51:04 +01:00
|
|
|
}};
|
2006-02-20 07:49:16 +01:00
|
|
|
|
2006-02-20 20:30:23 +01:00
|
|
|
|
2006-02-20 07:49:16 +01:00
|
|
|
output exec {{
|
|
|
|
|
|
|
|
/// CLEAR ALL CPU INST/EXE HAZARDS
|
|
|
|
inline void
|
|
|
|
clear_exe_inst_hazards()
|
|
|
|
{
|
|
|
|
//CODE HERE
|
|
|
|
}
|
2006-02-22 09:33:35 +01:00
|
|
|
}};
|