Merge zizzer.eecs.umich.edu:/.automount/zower/eecshome/m5/newmem
into zizzer.eecs.umich.edu:/z/m5/Bitkeeper/sparco3 --HG-- extra : convert_revision : f17800685609d8353ec14676f45fbb123fc4e6c3
This commit is contained in:
commit
9e7dc34383
13 changed files with 175 additions and 208 deletions
|
@ -218,7 +218,7 @@ def template JumpOrBranchDecode {{
|
||||||
|
|
||||||
def format CondBranch(code) {{
|
def format CondBranch(code) {{
|
||||||
code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
|
code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
|
||||||
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
|
iop = InstObjParams(name, Name, 'Branch', code,
|
||||||
('IsDirectControl', 'IsCondControl'))
|
('IsDirectControl', 'IsCondControl'))
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
|
@ -230,8 +230,7 @@ let {{
|
||||||
def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
|
def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
|
||||||
# Declare basic control transfer w/o link (i.e. link reg is R31)
|
# Declare basic control transfer w/o link (i.e. link reg is R31)
|
||||||
nolink_code = 'NPC = %s;\n' % npc_expr
|
nolink_code = 'NPC = %s;\n' % npc_expr
|
||||||
nolink_iop = InstObjParams(name, Name, base_class,
|
nolink_iop = InstObjParams(name, Name, base_class, nolink_code, flags)
|
||||||
CodeBlock(nolink_code), flags)
|
|
||||||
header_output = BasicDeclare.subst(nolink_iop)
|
header_output = BasicDeclare.subst(nolink_iop)
|
||||||
decoder_output = BasicConstructor.subst(nolink_iop)
|
decoder_output = BasicConstructor.subst(nolink_iop)
|
||||||
exec_output = BasicExecute.subst(nolink_iop)
|
exec_output = BasicExecute.subst(nolink_iop)
|
||||||
|
@ -239,7 +238,7 @@ def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
|
||||||
# Generate declaration of '*AndLink' version, append to decls
|
# Generate declaration of '*AndLink' version, append to decls
|
||||||
link_code = 'Ra = NPC & ~3;\n' + nolink_code
|
link_code = 'Ra = NPC & ~3;\n' + nolink_code
|
||||||
link_iop = InstObjParams(name, Name + 'AndLink', base_class,
|
link_iop = InstObjParams(name, Name + 'AndLink', base_class,
|
||||||
CodeBlock(link_code), flags)
|
link_code, flags)
|
||||||
header_output += BasicDeclare.subst(link_iop)
|
header_output += BasicDeclare.subst(link_iop)
|
||||||
decoder_output += BasicConstructor.subst(link_iop)
|
decoder_output += BasicConstructor.subst(link_iop)
|
||||||
exec_output += BasicExecute.subst(link_iop)
|
exec_output += BasicExecute.subst(link_iop)
|
||||||
|
|
|
@ -293,7 +293,7 @@ def template FloatingPointDecode {{
|
||||||
// currently unimplemented (will fail).
|
// currently unimplemented (will fail).
|
||||||
// - Generates NOP if FC == 31.
|
// - Generates NOP if FC == 31.
|
||||||
def format FloatingPointOperate(code, *opt_args) {{
|
def format FloatingPointOperate(code, *opt_args) {{
|
||||||
iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
|
iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
|
||||||
decode_block = FloatingPointDecode.subst(iop)
|
decode_block = FloatingPointDecode.subst(iop)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
|
@ -303,7 +303,7 @@ def format FloatingPointOperate(code, *opt_args) {{
|
||||||
// Special format for cvttq where rounding mode is pre-decoded
|
// Special format for cvttq where rounding mode is pre-decoded
|
||||||
def format FPFixedRounding(code, class_suffix, *opt_args) {{
|
def format FPFixedRounding(code, class_suffix, *opt_args) {{
|
||||||
Name += class_suffix
|
Name += class_suffix
|
||||||
iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
|
iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
|
||||||
decode_block = FloatingPointDecode.subst(iop)
|
decode_block = FloatingPointDecode.subst(iop)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
|
|
|
@ -113,16 +113,14 @@ def format IntegerOperate(code, *opt_flags) {{
|
||||||
imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code)
|
imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code)
|
||||||
|
|
||||||
# generate declaration for register version
|
# generate declaration for register version
|
||||||
cblk = CodeBlock(code)
|
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_flags)
|
||||||
iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags)
|
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
exec_output = BasicExecute.subst(iop)
|
exec_output = BasicExecute.subst(iop)
|
||||||
|
|
||||||
if uses_imm:
|
if uses_imm:
|
||||||
# append declaration for imm version
|
# append declaration for imm version
|
||||||
imm_cblk = CodeBlock(imm_code)
|
imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_code,
|
||||||
imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk,
|
|
||||||
opt_flags)
|
opt_flags)
|
||||||
header_output += BasicDeclare.subst(imm_iop)
|
header_output += BasicDeclare.subst(imm_iop)
|
||||||
decoder_output += BasicConstructor.subst(imm_iop)
|
decoder_output += BasicConstructor.subst(imm_iop)
|
||||||
|
|
|
@ -338,7 +338,7 @@ def template BasicDecodeWithMnemonic {{
|
||||||
|
|
||||||
// The most basic instruction format... used only for a few misc. insts
|
// The most basic instruction format... used only for a few misc. insts
|
||||||
def format BasicOperate(code, *flags) {{
|
def format BasicOperate(code, *flags) {{
|
||||||
iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), flags)
|
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, flags)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
|
@ -424,8 +424,7 @@ def template OperateNopCheckDecode {{
|
||||||
|
|
||||||
// Like BasicOperate format, but generates NOP if RC/FC == 31
|
// Like BasicOperate format, but generates NOP if RC/FC == 31
|
||||||
def format BasicOperateWithNopCheck(code, *opt_args) {{
|
def format BasicOperateWithNopCheck(code, *opt_args) {{
|
||||||
iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
|
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_args)
|
||||||
opt_args)
|
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = OperateNopCheckDecode.subst(iop)
|
decode_block = OperateNopCheckDecode.subst(iop)
|
||||||
|
|
|
@ -126,7 +126,7 @@ output decoder {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format LoadAddress(code) {{
|
def format LoadAddress(code) {{
|
||||||
iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
|
iop = InstObjParams(name, Name, 'MemoryDisp32', code)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
|
@ -191,22 +191,28 @@ def template CompleteAccDeclare {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
def template LoadStoreConstructor {{
|
def template EACompConstructor {{
|
||||||
/** TODO: change op_class to AddrGenOp or something (requires
|
/** TODO: change op_class to AddrGenOp or something (requires
|
||||||
* creating new member of OpClass enum in op_class.hh, updating
|
* creating new member of OpClass enum in op_class.hh, updating
|
||||||
* config files, etc.). */
|
* config files, etc.). */
|
||||||
inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
|
inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
||||||
{
|
{
|
||||||
%(ea_constructor)s;
|
%(constructor)s;
|
||||||
}
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
def template MemAccConstructor {{
|
||||||
inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
|
inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
||||||
{
|
{
|
||||||
%(memacc_constructor)s;
|
%(constructor)s;
|
||||||
}
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
def template LoadStoreConstructor {{
|
||||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||||
new EAComp(machInst), new MemAcc(machInst))
|
new EAComp(machInst), new MemAcc(machInst))
|
||||||
|
@ -227,7 +233,7 @@ def template EACompExecute {{
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(code)s;
|
%(ea_code)s;
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
|
@ -253,7 +259,7 @@ def template LoadMemAccExecute {{
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||||
%(code)s;
|
%(memacc_code)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
|
@ -352,7 +358,7 @@ def template StoreMemAccExecute {{
|
||||||
EA = xc->getEA();
|
EA = xc->getEA();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(code)s;
|
%(memacc_code)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
|
@ -497,7 +503,7 @@ def template MiscMemAccExecute {{
|
||||||
EA = xc->getEA();
|
EA = xc->getEA();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(code)s;
|
%(memacc_code)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
|
@ -582,63 +588,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||||
# add hook to get effective addresses into execution trace output.
|
# add hook to get effective addresses into execution trace output.
|
||||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
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,
|
# Some CPU models execute the memory operation as an atomic unit,
|
||||||
# while others want to separate them into an effective address
|
# while others want to separate them into an effective address
|
||||||
# computation and a memory access operation. As a result, we need
|
# computation and a memory access operation. As a result, we need
|
||||||
# to generate three StaticInst objects. Note that the latter two
|
# to generate three StaticInst objects. Note that the latter two
|
||||||
# are nested inside the larger "atomic" one.
|
# are nested inside the larger "atomic" one.
|
||||||
|
|
||||||
# generate InstObjParams for EAComp object
|
# Generate InstObjParams for each of the three objects. Note that
|
||||||
ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
|
# they differ only in the set of code objects contained (which in
|
||||||
|
# turn affects the object's overall operand list).
|
||||||
# generate InstObjParams for MemAcc object
|
iop = InstObjParams(name, Name, base_class,
|
||||||
memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
|
{ 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
|
||||||
# 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.startswith('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)
|
inst_flags)
|
||||||
|
ea_iop = InstObjParams(name, Name, base_class,
|
||||||
completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
|
{ 'ea_code':ea_code },
|
||||||
|
inst_flags)
|
||||||
|
memacc_iop = InstObjParams(name, Name, base_class,
|
||||||
|
{ 'memacc_code':memacc_code, 'postacc_code':postacc_code },
|
||||||
inst_flags)
|
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.startswith('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:
|
if mem_flags:
|
||||||
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
||||||
|
@ -659,13 +626,16 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||||
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
||||||
|
|
||||||
# (header_output, decoder_output, decode_block, exec_output)
|
# (header_output, decoder_output, decode_block, exec_output)
|
||||||
return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
|
return (LoadStoreDeclare.subst(iop),
|
||||||
|
EACompConstructor.subst(ea_iop)
|
||||||
|
+ MemAccConstructor.subst(memacc_iop)
|
||||||
|
+ LoadStoreConstructor.subst(iop),
|
||||||
decode_template.subst(iop),
|
decode_template.subst(iop),
|
||||||
EACompExecute.subst(ea_iop)
|
EACompExecute.subst(ea_iop)
|
||||||
+ memAccExecTemplate.subst(memacc_iop)
|
+ memAccExecTemplate.subst(memacc_iop)
|
||||||
+ fullExecTemplate.subst(iop)
|
+ fullExecTemplate.subst(iop)
|
||||||
+ initiateAccTemplate.subst(initiateacc_iop)
|
+ initiateAccTemplate.subst(iop)
|
||||||
+ completeAccTemplate.subst(completeacc_iop))
|
+ completeAccTemplate.subst(iop))
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||||
|
|
|
@ -68,7 +68,7 @@ output decoder {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format EmulatedCallPal(code, *flags) {{
|
def format EmulatedCallPal(code, *flags) {{
|
||||||
iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags)
|
iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
|
@ -131,7 +131,7 @@ output decoder {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format CallPal(code, *flags) {{
|
def format CallPal(code, *flags) {{
|
||||||
iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags)
|
iop = InstObjParams(name, Name, 'CallPalBase', code, flags)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
|
@ -269,8 +269,7 @@ output decoder {{
|
||||||
def format HwMoveIPR(code, *flags) {{
|
def format HwMoveIPR(code, *flags) {{
|
||||||
all_flags = ['IprAccessOp']
|
all_flags = ['IprAccessOp']
|
||||||
all_flags += flags
|
all_flags += flags
|
||||||
iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
|
iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags)
|
||||||
all_flags)
|
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
|
|
|
@ -1017,37 +1017,38 @@ class Template:
|
||||||
# CPU-model-specific substitutions are handled later (in GenCode).
|
# CPU-model-specific substitutions are handled later (in GenCode).
|
||||||
template = protect_cpu_symbols(template)
|
template = protect_cpu_symbols(template)
|
||||||
|
|
||||||
# if we're dealing with an InstObjParams object, we need to be a
|
# Build a dict ('myDict') to use for the template substitution.
|
||||||
# little more sophisticated. Otherwise, just do what we've always
|
# Start with the template namespace. Make a copy since we're
|
||||||
# done
|
# going to modify it.
|
||||||
|
myDict = templateMap.copy()
|
||||||
|
|
||||||
if isinstance(d, InstObjParams):
|
if isinstance(d, InstObjParams):
|
||||||
# The instruction wide parameters are already formed, but the
|
# If we're dealing with an InstObjParams object, we need
|
||||||
# parameters which are only function wide still need to be
|
# to be a little more sophisticated. The instruction-wide
|
||||||
# generated.
|
# parameters are already formed, but the parameters which
|
||||||
perFuncNames = ['op_decl', 'op_src_decl', 'op_dest_decl', \
|
# are only function wide still need to be generated.
|
||||||
'op_rd', 'op_wb', 'mem_acc_size', 'mem_acc_type']
|
|
||||||
compositeCode = ''
|
compositeCode = ''
|
||||||
|
|
||||||
myDict = templateMap.copy()
|
|
||||||
myDict.update(d.__dict__)
|
myDict.update(d.__dict__)
|
||||||
# The "operands" and "snippets" attributes of the InstObjParams
|
# The "operands" and "snippets" attributes of the InstObjParams
|
||||||
# objects are for internal use and not substitution.
|
# objects are for internal use and not substitution.
|
||||||
del myDict['operands']
|
del myDict['operands']
|
||||||
del myDict['snippets']
|
del myDict['snippets']
|
||||||
|
|
||||||
for name in labelRE.findall(template):
|
snippetLabels = [l for l in labelRE.findall(template)
|
||||||
# Don't try to find a snippet to go with things that will
|
if d.snippets.has_key(l)]
|
||||||
# match against attributes of d, or that are other templates,
|
|
||||||
# or that we're going to generate later, or that we've already
|
snippets = dict([(s, mungeSnippet(d.snippets[s]))
|
||||||
# found.
|
for s in snippetLabels])
|
||||||
if not hasattr(d, name) and \
|
|
||||||
not templateMap.has_key(name) and \
|
myDict.update(snippets)
|
||||||
not myDict.has_key(name) and \
|
|
||||||
name not in perFuncNames:
|
compositeCode = ' '.join(map(str, snippets.values()))
|
||||||
myDict[name] = d.snippets[name]
|
|
||||||
if isinstance(myDict[name], str):
|
# Add in template itself in case it references any
|
||||||
myDict[name] = substMungedOpNames(substBitOps(myDict[name]))
|
# operands explicitly (like Mem)
|
||||||
compositeCode += (" " + myDict[name])
|
compositeCode += ' ' + template
|
||||||
|
|
||||||
operands = SubOperandList(compositeCode, d.operands)
|
operands = SubOperandList(compositeCode, d.operands)
|
||||||
|
|
||||||
myDict['op_decl'] = operands.concatAttrStrings('op_decl')
|
myDict['op_decl'] = operands.concatAttrStrings('op_decl')
|
||||||
|
@ -1067,15 +1068,11 @@ class Template:
|
||||||
myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
|
myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
|
||||||
myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
|
myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
|
||||||
|
|
||||||
else:
|
elif isinstance(d, dict):
|
||||||
# Start with the template namespace. Make a copy since we're
|
|
||||||
# going to modify it.
|
|
||||||
myDict = templateMap.copy()
|
|
||||||
# if the argument is a dictionary, we just use it.
|
# if the argument is a dictionary, we just use it.
|
||||||
if isinstance(d, dict):
|
|
||||||
myDict.update(d)
|
myDict.update(d)
|
||||||
# if the argument is an object, we use its attribute map.
|
|
||||||
elif hasattr(d, '__dict__'):
|
elif hasattr(d, '__dict__'):
|
||||||
|
# if the argument is an object, we use its attribute map.
|
||||||
myDict.update(d.__dict__)
|
myDict.update(d.__dict__)
|
||||||
else:
|
else:
|
||||||
raise TypeError, "Template.subst() arg must be or have dictionary"
|
raise TypeError, "Template.subst() arg must be or have dictionary"
|
||||||
|
@ -1662,8 +1659,12 @@ assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
|
||||||
def substMungedOpNames(code):
|
def substMungedOpNames(code):
|
||||||
return operandsWithExtRE.sub(r'\1', code)
|
return operandsWithExtRE.sub(r'\1', code)
|
||||||
|
|
||||||
def joinLists(t):
|
# Fix up code snippets for final substitution in templates.
|
||||||
return map(string.join, t)
|
def mungeSnippet(s):
|
||||||
|
if isinstance(s, str):
|
||||||
|
return substMungedOpNames(substBitOps(s))
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
|
||||||
def makeFlagConstructor(flag_list):
|
def makeFlagConstructor(flag_list):
|
||||||
if len(flag_list) == 0:
|
if len(flag_list) == 0:
|
||||||
|
@ -1689,17 +1690,13 @@ opClassRE = re.compile(r'.*Op|No_OpClass')
|
||||||
|
|
||||||
class InstObjParams:
|
class InstObjParams:
|
||||||
def __init__(self, mnem, class_name, base_class = '',
|
def __init__(self, mnem, class_name, base_class = '',
|
||||||
snippets = None, opt_args = []):
|
snippets = {}, opt_args = []):
|
||||||
self.mnemonic = mnem
|
self.mnemonic = mnem
|
||||||
self.class_name = class_name
|
self.class_name = class_name
|
||||||
self.base_class = base_class
|
self.base_class = base_class
|
||||||
compositeCode = ''
|
|
||||||
if snippets:
|
|
||||||
if not isinstance(snippets, dict):
|
if not isinstance(snippets, dict):
|
||||||
snippets = {'code' : snippets}
|
snippets = {'code' : snippets}
|
||||||
for snippet in snippets.values():
|
compositeCode = ' '.join(map(str, snippets.values()))
|
||||||
if isinstance(snippet, str):
|
|
||||||
compositeCode += (" " + snippet)
|
|
||||||
self.snippets = snippets
|
self.snippets = snippets
|
||||||
|
|
||||||
self.operands = OperandList(compositeCode)
|
self.operands = OperandList(compositeCode)
|
||||||
|
|
|
@ -154,19 +154,20 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||||
|
|
||||||
0x3: decode FUNCTION_LO {
|
0x3: decode FUNCTION_LO {
|
||||||
format HiLoOp {
|
format HiLoOp {
|
||||||
0x0: mult({{ val = Rs.sd * Rt.sd; }});
|
0x0: mult({{ int64_t val = Rs.sd * Rt.sd; }});
|
||||||
0x1: multu({{ val = Rs.ud * Rt.ud; }});
|
0x1: multu({{ uint64_t val = Rs.ud * Rt.ud; }});
|
||||||
}
|
0x2: div({{ int64_t val;
|
||||||
|
if (Rt.sd != 0) {
|
||||||
format HiLoMiscOp {
|
int64_t hi = Rs.sd % Rt.sd;
|
||||||
0x2: div({{ if (Rt.sd != 0) {
|
int64_t lo = Rs.sd / Rt.sd;
|
||||||
HI = Rs.sd % Rt.sd;
|
val = (hi << 32) | lo;
|
||||||
LO = Rs.sd / Rt.sd;
|
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
0x3: divu({{ if (Rt.ud != 0) {
|
0x3: divu({{ uint64_t val;
|
||||||
HI = Rs.ud % Rt.ud;
|
if (Rt.ud != 0) {
|
||||||
LO = Rs.ud / Rt.ud;
|
uint64_t hi = Rs.ud % Rt.ud;
|
||||||
|
uint64_t lo = Rs.ud / Rt.ud;
|
||||||
|
val = (hi << 32) | lo;
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
@ -950,16 +951,16 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||||
}});
|
}});
|
||||||
|
|
||||||
format HiLoOp {
|
format HiLoOp {
|
||||||
0x0: madd({{ val = ((int64_t) HI << 32 | LO) +
|
0x0: madd({{ int64_t val = ((int64_t) HI << 32 | LO) +
|
||||||
(Rs.sd * Rt.sd);
|
(Rs.sd * Rt.sd);
|
||||||
}});
|
}});
|
||||||
0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) +
|
0x1: maddu({{ uint64_t val = ((uint64_t) HI << 32 | LO) +
|
||||||
(Rs.ud * Rt.ud);
|
(Rs.ud * Rt.ud);
|
||||||
}});
|
}});
|
||||||
0x4: msub({{ val = ((int64_t) HI << 32 | LO) -
|
0x4: msub({{ int64_t val = ((int64_t) HI << 32 | LO) -
|
||||||
(Rs.sd * Rt.sd);
|
(Rs.sd * Rt.sd);
|
||||||
}});
|
}});
|
||||||
0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) -
|
0x5: msubu({{ uint64_t val = ((uint64_t) HI << 32 | LO) -
|
||||||
(Rs.ud * Rt.ud);
|
(Rs.ud * Rt.ud);
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,11 +240,6 @@ def format IntImmOp(code, *opt_flags) {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format HiLoOp(code, *opt_flags) {{
|
def format HiLoOp(code, *opt_flags) {{
|
||||||
if '.sd' in code:
|
|
||||||
code = 'int64_t ' + code
|
|
||||||
elif '.ud' in code:
|
|
||||||
code = 'uint64_t ' + code
|
|
||||||
|
|
||||||
code += 'HI = val<63:32>;\n'
|
code += 'HI = val<63:32>;\n'
|
||||||
code += 'LO = val<31:0>;\n'
|
code += 'LO = val<31:0>;\n'
|
||||||
|
|
||||||
|
@ -260,7 +255,7 @@ def format HiLoMiscOp(code, *opt_flags) {{
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = HiLoExecute.subst(iop)
|
exec_output = BasicExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -166,22 +166,28 @@ def template CompleteAccDeclare {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
def template LoadStoreConstructor {{
|
def template EACompConstructor {{
|
||||||
/** TODO: change op_class to AddrGenOp or something (requires
|
/** TODO: change op_class to AddrGenOp or something (requires
|
||||||
* creating new member of OpClass enum in op_class.hh, updating
|
* creating new member of OpClass enum in op_class.hh, updating
|
||||||
* config files, etc.). */
|
* config files, etc.). */
|
||||||
inline %(class_name)s::EAComp::EAComp(MachInst machInst)
|
inline %(class_name)s::EAComp::EAComp(MachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
||||||
{
|
{
|
||||||
%(ea_constructor)s;
|
%(constructor)s;
|
||||||
}
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
def template MemAccConstructor {{
|
||||||
inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
|
inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
||||||
{
|
{
|
||||||
%(memacc_constructor)s;
|
%(constructor)s;
|
||||||
}
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
def template LoadStoreConstructor {{
|
||||||
inline %(class_name)s::%(class_name)s(MachInst machInst)
|
inline %(class_name)s::%(class_name)s(MachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||||
new EAComp(machInst), new MemAcc(machInst))
|
new EAComp(machInst), new MemAcc(machInst))
|
||||||
|
@ -202,7 +208,7 @@ def template EACompExecute {{
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(code)s;
|
%(ea_code)s;
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
|
@ -228,7 +234,7 @@ def template LoadMemAccExecute {{
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||||
%(code)s;
|
%(memacc_code)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
|
@ -327,7 +333,7 @@ def template StoreMemAccExecute {{
|
||||||
EA = xc->getEA();
|
EA = xc->getEA();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(code)s;
|
%(memacc_code)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
|
@ -471,7 +477,7 @@ def template MiscMemAccExecute {{
|
||||||
EA = xc->getEA();
|
EA = xc->getEA();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(code)s;
|
%(memacc_code)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
|
|
|
@ -40,63 +40,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||||
# add hook to get effective addresses into execution trace output.
|
# add hook to get effective addresses into execution trace output.
|
||||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
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,
|
# Some CPU models execute the memory operation as an atomic unit,
|
||||||
# while others want to separate them into an effective address
|
# while others want to separate them into an effective address
|
||||||
# computation and a memory access operation. As a result, we need
|
# computation and a memory access operation. As a result, we need
|
||||||
# to generate three StaticInst objects. Note that the latter two
|
# to generate three StaticInst objects. Note that the latter two
|
||||||
# are nested inside the larger "atomic" one.
|
# are nested inside the larger "atomic" one.
|
||||||
|
|
||||||
# generate InstObjParams for EAComp object
|
# Generate InstObjParams for each of the three objects. Note that
|
||||||
ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
|
# they differ only in the set of code objects contained (which in
|
||||||
|
# turn affects the object's overall operand list).
|
||||||
# generate InstObjParams for MemAcc object
|
iop = InstObjParams(name, Name, base_class,
|
||||||
memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
|
{ 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
|
||||||
# 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.startswith('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)
|
inst_flags)
|
||||||
|
ea_iop = InstObjParams(name, Name, base_class,
|
||||||
completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
|
{ 'ea_code':ea_code },
|
||||||
|
inst_flags)
|
||||||
|
memacc_iop = InstObjParams(name, Name, base_class,
|
||||||
|
{ 'memacc_code':memacc_code, 'postacc_code':postacc_code },
|
||||||
inst_flags)
|
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.startswith('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:
|
if mem_flags:
|
||||||
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
|
||||||
|
@ -117,14 +78,19 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||||
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
|
||||||
|
|
||||||
# (header_output, decoder_output, decode_block, exec_output)
|
# (header_output, decoder_output, decode_block, exec_output)
|
||||||
return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
|
return (LoadStoreDeclare.subst(iop),
|
||||||
|
EACompConstructor.subst(ea_iop)
|
||||||
|
+ MemAccConstructor.subst(memacc_iop)
|
||||||
|
+ LoadStoreConstructor.subst(iop),
|
||||||
decode_template.subst(iop),
|
decode_template.subst(iop),
|
||||||
EACompExecute.subst(ea_iop)
|
EACompExecute.subst(ea_iop)
|
||||||
+ memAccExecTemplate.subst(memacc_iop)
|
+ memAccExecTemplate.subst(memacc_iop)
|
||||||
+ fullExecTemplate.subst(iop)
|
+ fullExecTemplate.subst(iop)
|
||||||
+ initiateAccTemplate.subst(initiateacc_iop)
|
+ initiateAccTemplate.subst(iop)
|
||||||
+ completeAccTemplate.subst(completeacc_iop))
|
+ completeAccTemplate.subst(iop))
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
output header {{
|
output header {{
|
||||||
std::string inst2string(MachInst machInst);
|
std::string inst2string(MachInst machInst);
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -170,7 +170,6 @@ def template LoadInitiateAcc {{
|
||||||
{
|
{
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
Addr EA;
|
Addr EA;
|
||||||
uint%(mem_acc_size)s_t Mem;
|
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
|
|
|
@ -123,6 +123,44 @@ class AlphaDynInst : public BaseDynInst<Impl>
|
||||||
this->threadNumber);
|
this->threadNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Reads a miscellaneous register. */
|
||||||
|
TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
|
||||||
|
{
|
||||||
|
return this->cpu->readMiscReg(
|
||||||
|
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||||
|
this->threadNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reads a misc. register, including any side-effects the read
|
||||||
|
* might have as defined by the architecture.
|
||||||
|
*/
|
||||||
|
TheISA::MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
|
||||||
|
{
|
||||||
|
return this->cpu->readMiscRegWithEffect(
|
||||||
|
si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||||
|
this->threadNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets a misc. register. */
|
||||||
|
void setMiscRegOperand(const StaticInst * si, int idx, const MiscReg &val)
|
||||||
|
{
|
||||||
|
this->instResult.integer = val;
|
||||||
|
return this->cpu->setMiscReg(
|
||||||
|
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||||
|
val, this->threadNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets a misc. register, including any side-effects the write
|
||||||
|
* might have as defined by the architecture.
|
||||||
|
*/
|
||||||
|
void setMiscRegOperandWithEffect(const StaticInst *si, int idx,
|
||||||
|
const MiscReg &val)
|
||||||
|
{
|
||||||
|
return this->cpu->setMiscRegWithEffect(
|
||||||
|
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
|
||||||
|
val, this->threadNumber);
|
||||||
|
}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
/** Calls hardware return from error interrupt. */
|
/** Calls hardware return from error interrupt. */
|
||||||
Fault hwrei();
|
Fault hwrei();
|
||||||
|
|
Loading…
Reference in a new issue