Changes to the isa_parser and affected files to fix an indexing problem with split execute instructions and miscregs aliasing with integer registers.

src/arch/isa_parser.py:
    Rearranged things so that classes with more than one execute function treat operands properly.
    1. Eliminated the CodeBlock class
    2. Created a SubOperandList
    3. Redefined how InstObjParams is constructed

    To define an InstObjParam, you can either pass in a single code literal which will be named "code", or you can pass in a dictionary of code snippets which will be substituted into the Templates. In order to get this to work, there is a new restriction that each template has only one function in it. These changes should only affect memory instructions which have regular and split execute functions.

    Also changed the MiscRegs so that they use the instrunctions srcReg and destReg arrays.
src/arch/sparc/isa/formats/basic.isa:
src/arch/sparc/isa/formats/branch.isa:
src/arch/sparc/isa/formats/integerop.isa:
src/arch/sparc/isa/formats/mem/basicmem.isa:
src/arch/sparc/isa/formats/mem/blockmem.isa:
src/arch/sparc/isa/formats/mem/util.isa:
src/arch/sparc/isa/formats/nop.isa:
src/arch/sparc/isa/formats/priv.isa:
src/arch/sparc/isa/formats/trap.isa:
    Rearranged to work with new InstObjParam scheme.
src/cpu/o3/sparc/dyn_inst.hh:
    Added functions to access the miscregs using the indexes from instructions srcReg and destReg arrays. Also changed the names of the other accessors so that they have the suffix "Operand" if they use those arrays.
src/cpu/simple/base.hh:
    Added functions to access the miscregs using the indexes from instructions srcReg and destReg arrays.

--HG--
extra : convert_revision : c91e1073138b72bcf4113a721e0ed40ec600cf2e
This commit is contained in:
Gabe Black 2006-12-16 07:10:04 -05:00
parent 90907f6b3c
commit 6aa06a26b7
12 changed files with 294 additions and 172 deletions

View file

@ -808,8 +808,7 @@ class GenCode:
# a defineInst() method that generates the code for an instruction
# definition.
exportContextSymbols = ('InstObjParams', 'CodeBlock',
'makeList', 're', 'string')
exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
exportContext = {}
@ -1003,27 +1002,83 @@ def substBitOps(code):
# Template objects are format strings that allow substitution from
# the attribute spaces of other objects (e.g. InstObjParams instances).
labelRE = re.compile(r'[^%]%\(([^\)]+)\)[sd]')
class Template:
def __init__(self, t):
self.template = t
def subst(self, d):
# 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 isinstance(d, dict):
myDict.update(d)
# if the argument is an object, we use its attribute map.
elif hasattr(d, '__dict__'):
myDict.update(d.__dict__)
else:
raise TypeError, "Template.subst() arg must be or have dictionary"
myDict = None
# Protect non-Python-dict substitutions (e.g. if there's a printf
# in the templated C++ code)
template = protect_non_subst_percents(self.template)
# CPU-model-specific substitutions are handled later (in GenCode).
template = protect_cpu_symbols(template)
# if we're dealing with an InstObjParams object, we need to be a
# little more sophisticated. Otherwise, just do what we've always
# done
if isinstance(d, InstObjParams):
# The instruction wide parameters are already formed, but the
# parameters which are only function wide still need to be
# generated.
perFuncNames = ['op_decl', 'op_src_decl', 'op_dest_decl', \
'op_rd', 'op_wb', 'mem_acc_size', 'mem_acc_type']
compositeCode = ''
myDict = templateMap.copy()
myDict.update(d.__dict__)
# The "operands" and "snippets" attributes of the InstObjParams
# objects are for internal use and not substitution.
del myDict['operands']
del myDict['snippets']
for name in labelRE.findall(template):
# Don't try to find a snippet to go with things that will
# match against attributes of d, or that are other templates,
# or that we're going to generate later, or that we've already
# found.
if not hasattr(d, name) and \
not templateMap.has_key(name) and \
not myDict.has_key(name) and \
name not in perFuncNames:
myDict[name] = d.snippets[name]
if isinstance(myDict[name], str):
myDict[name] = substMungedOpNames(substBitOps(myDict[name]))
compositeCode += (" " + myDict[name])
operands = SubOperandList(compositeCode, d.operands)
myDict['op_decl'] = operands.concatAttrStrings('op_decl')
is_src = lambda op: op.is_src
is_dest = lambda op: op.is_dest
myDict['op_src_decl'] = \
operands.concatSomeAttrStrings(is_src, 'op_src_decl')
myDict['op_dest_decl'] = \
operands.concatSomeAttrStrings(is_dest, 'op_dest_decl')
myDict['op_rd'] = operands.concatAttrStrings('op_rd')
myDict['op_wb'] = operands.concatAttrStrings('op_wb')
if d.operands.memOperand:
myDict['mem_acc_size'] = d.operands.memOperand.mem_acc_size
myDict['mem_acc_type'] = d.operands.memOperand.mem_acc_type
else:
# 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 isinstance(d, dict):
myDict.update(d)
# if the argument is an object, we use its attribute map.
elif hasattr(d, '__dict__'):
myDict.update(d.__dict__)
else:
raise TypeError, "Template.subst() arg must be or have dictionary"
return template % myDict
# Convert to string. This handles the case when a template with a
@ -1296,10 +1351,10 @@ class ControlRegOperand(Operand):
def makeConstructor(self):
c = ''
if self.is_src:
c += '\n\t_srcRegIdx[%d] = %s;' % \
c += '\n\t_srcRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
(self.src_reg_idx, self.reg_spec)
if self.is_dest:
c += '\n\t_destRegIdx[%d] = %s;' % \
c += '\n\t_destRegIdx[%d] = %s + Ctrl_Base_DepTag;' % \
(self.dest_reg_idx, self.reg_spec)
return c
@ -1307,7 +1362,7 @@ class ControlRegOperand(Operand):
bit_select = 0
if (self.ctype == 'float' or self.ctype == 'double'):
error(0, 'Attempt to read control register as FP')
base = 'xc->readMiscReg(%s)' % self.reg_spec
base = 'xc->readMiscRegOperand(this, %s)' % self.src_reg_idx
if self.size == self.dflt_size:
return '%s = %s;\n' % (self.base_name, base)
else:
@ -1317,7 +1372,8 @@ class ControlRegOperand(Operand):
def makeWrite(self):
if (self.ctype == 'float' or self.ctype == 'double'):
error(0, 'Attempt to write control register as FP')
wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name)
wb = 'xc->setMiscRegOperandWithEffect(this, %s, %s);\n' % \
(self.dest_reg_idx, self.base_name)
wb += 'if (traceData) { traceData->setData(%s); }' % \
self.base_name
return wb
@ -1550,6 +1606,48 @@ class OperandList:
def sort(self):
self.items.sort(lambda a, b: a.sort_pri - b.sort_pri)
class SubOperandList(OperandList):
# Find all the operands in the given code block. Returns an operand
# descriptor list (instance of class OperandList).
def __init__(self, code, master_list):
self.items = []
self.bases = {}
# delete comments so we don't match on reg specifiers inside
code = commentRE.sub('', code)
# search for operands
next_pos = 0
while 1:
match = operandsRE.search(code, next_pos)
if not match:
# no more matches: we're done
break
op = match.groups()
# regexp groups are operand full name, base, and extension
(op_full, op_base, op_ext) = op
# find this op in the master list
op_desc = master_list.find_base(op_base)
if not op_desc:
error(0, 'Found operand %s which is not in the master list!' \
' This is an internal error' % \
op_base)
else:
# See if we've already found this operand
op_desc = self.find_base(op_base)
if not op_desc:
# if not, add a reference to it to this sub list
self.append(master_list.bases[op_base])
# start next search after end of current match
next_pos = match.end()
self.sort()
self.memOperand = None
for op_desc in self.items:
if op_desc.isMem():
if self.memOperand:
error(0, "Code block has more than one memory operand.")
self.memOperand = op_desc
# Regular expression object to match C++ comments
# (used in findOperands())
commentRE = re.compile(r'//.*\n')
@ -1583,11 +1681,28 @@ def makeFlagConstructor(flag_list):
code = pre + string.join(flag_list, post + pre) + post
return code
class CodeBlock:
def __init__(self, code):
self.orig_code = code
self.operands = OperandList(code)
self.code = substMungedOpNames(substBitOps(code))
# Assume all instruction flags are of the form 'IsFoo'
instFlagRE = re.compile(r'Is.*')
# OpClass constants end in 'Op' except No_OpClass
opClassRE = re.compile(r'.*Op|No_OpClass')
class InstObjParams:
def __init__(self, mnem, class_name, base_class = '',
snippets = None, opt_args = []):
self.mnemonic = mnem
self.class_name = class_name
self.base_class = base_class
compositeCode = ''
if snippets:
if not isinstance(snippets, dict):
snippets = {'code' : snippets}
for snippet in snippets.values():
if isinstance(snippet, str):
compositeCode += (" " + snippet)
self.snippets = snippets
self.operands = OperandList(compositeCode)
self.constructor = self.operands.concatAttrStrings('constructor')
self.constructor += \
'\n\t_numSrcRegs = %d;' % self.operands.numSrcRegs
@ -1597,28 +1712,10 @@ class CodeBlock:
'\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs
self.constructor += \
'\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs
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')
self.flags = self.operands.concatAttrLists('flags')
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
# These are good enough for most cases, and can be overridden
# later otherwise.
if 'IsStore' in self.flags:
self.op_class = 'MemWriteOp'
@ -1629,48 +1726,6 @@ class CodeBlock:
else:
self.op_class = 'IntAluOp'
# Assume all instruction flags are of the form 'IsFoo'
instFlagRE = re.compile(r'Is.*')
# OpClass constants end in 'Op' except No_OpClass
opClassRE = re.compile(r'.*Op|No_OpClass')
class InstObjParams:
def __init__(self, mnem, class_name, base_class = '',
code = None, opt_args = [], extras = {}):
self.mnemonic = mnem
self.class_name = class_name
self.base_class = base_class
if code:
#If the user already made a CodeBlock, pick the parts from it
if isinstance(code, CodeBlock):
origCode = code.orig_code
codeBlock = code
else:
origCode = code
codeBlock = CodeBlock(code)
stringExtras = {}
otherExtras = {}
for (k, v) in extras.items():
if type(v) == str:
stringExtras[k] = v
else:
otherExtras[k] = v
compositeCode = "\n".join([origCode] + stringExtras.values())
# compositeCode = '\n'.join([origCode] +
# [pair[1] for pair in extras])
compositeBlock = CodeBlock(compositeCode)
for code_attr in compositeBlock.__dict__.keys():
setattr(self, code_attr, getattr(compositeBlock, code_attr))
for (key, snippet) in stringExtras.items():
setattr(self, key, CodeBlock(snippet).code)
for (key, item) in otherExtras.items():
setattr(self, key, item)
self.code = codeBlock.code
self.orig_code = origCode
else:
self.constructor = ''
self.flags = []
# Optional arguments are assumed to be either StaticInst flags
# or an OpClass value. To avoid having to import a complete
# list of these values to match against, we do it ad-hoc

View file

@ -95,8 +95,7 @@ def template BasicDecodeWithMnemonic {{
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst',
CodeBlock(code), flags)
iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)

View file

@ -248,7 +248,6 @@ def format Branch(code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchN(bits, code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
new_opt_flags = []
for flag in opt_flags:
if flag == ',a':
@ -256,7 +255,7 @@ def format BranchN(bits, code, *opt_flags) {{
Name += 'Annul'
else:
new_opt_flags += flag
iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags)
iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
@ -266,8 +265,7 @@ def format BranchN(bits, code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchSplit(code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)

View file

@ -263,14 +263,15 @@ let {{
def doIntFormat(code, ccCode, name, Name, opt_flags):
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'IntOp', code,
opt_flags, {"cc_code": ccCode})
iop = InstObjParams(name, Name, 'IntOp',
{"code": code, "cc_code": ccCode},
opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
immCode, opt_flags, {"cc_code": ccCode})
{"code": immCode, "cc_code": ccCode}, opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += IntOpExecute.subst(imm_iop)
@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{
def format SetHi(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SetHi',
code, opt_flags, {"cc_code": ''})
{"code": code, "cc_code": ''}, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)

View file

@ -55,15 +55,20 @@ let {{
def doMemFormat(code, execute, faultCode, name, Name, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem', code,
opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg})
iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm})
iop = InstObjParams(name, Name, 'Mem',
{"code": code, "fault_check": faultCode,
"ea_code": addrCalcReg},
opt_flags)
iop_imm = InstObjParams(name, Name + "Imm", 'MemImm',
{"code": code, "fault_check": faultCode,
"ea_code": addrCalcImm},
opt_flags)
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, execute,
faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags)
exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm,
execute, faultCode, name, name + "Imm",
Name, Name + "Imm", opt_flags)
return (header_output, decoder_output, exec_output, decode_block)
}};
@ -71,7 +76,7 @@ def format LoadAlt(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, LoadExecute,
decode_block) = doMemFormat(code, LoadFuncs,
AlternateAsiPrivFaultCheck, name, Name, opt_flags)
}};
@ -79,7 +84,7 @@ def format StoreAlt(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, StoreExecute,
decode_block) = doMemFormat(code, StoreFuncs,
AlternateAsiPrivFaultCheck, name, Name, opt_flags)
}};
@ -88,7 +93,7 @@ def format Load(code, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
LoadExecute, '', name, Name, opt_flags)
LoadFuncs, '', name, Name, opt_flags)
}};
def format Store(code, *opt_flags) {{
@ -96,5 +101,5 @@ def format Store(code, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
StoreExecute, '', name, Name, opt_flags)
StoreFuncs, '', name, Name, opt_flags)
}};

View file

@ -293,14 +293,14 @@ let {{
else:
flag_code = "flags[IsDelayedCommit] = true;"
pcedCode = matcher.sub("Frd_%d" % microPc, code)
iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
opt_flags, {"ea_code": addrCalcReg,
iop = InstObjParams(name, Name, 'BlockMem',
{"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
"set_flags": flag_code})
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
opt_flags, {"ea_code": addrCalcImm,
"set_flags": flag_code}, opt_flags)
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
{"code": pcedCode, "ea_code": addrCalcImm,
"fault_check": faultCode, "micro_pc": microPc,
"set_flags": flag_code})
"set_flags": flag_code}, opt_flags)
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
@ -315,25 +315,25 @@ let {{
}};
def format BlockLoad(code, *opt_flags) {{
# We need to make sure to check the highest priority fault last.
# That way, if other faults have been detected, they'll be overwritten
# rather than the other way around.
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
(header_output,
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
LoadExecute, name, Name, opt_flags)
# We need to make sure to check the highest priority fault last.
# That way, if other faults have been detected, they'll be overwritten
# rather than the other way around.
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
(header_output,
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
LoadFuncs, name, Name, opt_flags)
}};
def format BlockStore(code, *opt_flags) {{
# We need to make sure to check the highest priority fault last.
# That way, if other faults have been detected, they'll be overwritten
# rather than the other way around.
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
(header_output,
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
StoreExecute, name, Name, opt_flags)
# We need to make sure to check the highest priority fault last.
# That way, if other faults have been detected, they'll be overwritten
# rather than the other way around.
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
(header_output,
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
StoreFuncs, name, Name, opt_flags)
}};

View file

@ -162,15 +162,17 @@ def template LoadExecute {{
return fault;
}
}};
def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
Addr EA;
uint%(mem_acc_size)s_t Mem;
%(ea_decl)s;
%(ea_rd)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
@ -180,18 +182,20 @@ def template LoadExecute {{
}
return fault;
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
%(code_decl)s;
%(code_rd)s;
%(op_decl)s;
%(op_rd)s;
Mem = pkt->get<typeof(Mem)>();
%(code)s;
if(fault == NoFault)
{
%(code_wb)s;
%(op_wb)s;
}
return fault;
}
@ -228,7 +232,9 @@ def template StoreExecute {{
return fault;
}
}};
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
@ -255,7 +261,9 @@ def template StoreExecute {{
}
return fault;
}
}};
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
@ -275,6 +283,8 @@ def template CompleteAccDeclare {{
//Here are some code snippets which check for various fault conditions
let {{
LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
# The LSB can be zero, since it's really the MSB in doubles and quads
# and we're dealing with doubles
BlockAlignmentFaultCheck = '''
@ -308,20 +318,10 @@ let {{
//and in the other they're distributed across two. Also note that for
//execute functions, the name of the base class doesn't matter.
let {{
def doSplitExecute(code, execute, name, Name, opt_flags, microParam):
codeParam = microParam.copy()
codeParam["ea_code"] = ''
codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam)
eaIop = InstObjParams(name, Name, '', microParam["ea_code"],
opt_flags, microParam)
iop = InstObjParams(name, Name, '', code, opt_flags, microParam)
(iop.ea_decl,
iop.ea_rd,
iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
(iop.code_decl,
iop.code_rd,
iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
return execute.subst(iop)
def doSplitExecute(execute, name, Name, opt_flags, microParam):
iop = InstObjParams(name, Name, '', microParam, opt_flags)
(execf, initf, compf) = execute
return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
@ -330,8 +330,9 @@ let {{
for (eaCode, name, Name) in (
(eaRegCode, nameReg, NameReg),
(eaImmCode, nameImm, NameImm)):
microParams = {"ea_code" : eaCode, "fault_check": faultCode}
executeCode += doSplitExecute(code, execute, name, Name,
microParams = {"code": code, "ea_code": eaCode,
"fault_check": faultCode}
executeCode += doSplitExecute(execute, name, Name,
opt_flags, microParams)
return executeCode
}};

View file

@ -88,9 +88,7 @@ def template NopExecute {{
// Primary format for integer operate instructions:
def format Nop(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags)
iop = InstObjParams(name, Name, 'Nop', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)

View file

@ -235,8 +235,9 @@ let {{
name = mnem
regBase = 'WrPriv'
break
iop = InstObjParams(name, Name, regBase, code,
opt_flags, {"check": checkCode, "reg_name": regName})
iop = InstObjParams(name, Name, regBase,
{"code": code, "check": checkCode, "reg_name": regName},
opt_flags)
header_output = BasicDeclare.subst(iop)
if regName == '':
decoder_output = BasicConstructor.subst(iop)
@ -245,7 +246,8 @@ let {{
exec_output = PrivExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
immCode, opt_flags, {"check": checkCode, "reg_name": regName})
{"code": immCode, "check": checkCode, "reg_name": regName},
opt_flags)
header_output += BasicDeclare.subst(imm_iop)
if regName == '':
decoder_output += BasicConstructor.subst(imm_iop)

View file

@ -83,9 +83,7 @@ def template TrapExecute {{
}};
def format Trap(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags)
iop = InstObjParams(name, Name, 'Trap', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)

View file

@ -106,6 +106,45 @@ class SparcDynInst : public BaseDynInst<Impl>
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 TheISA::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 TheISA::MiscReg &val)
{
return this->cpu->setMiscRegWithEffect(
si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
val, this->threadNumber);
}
#if FULL_SYSTEM
/** Calls hardware return from error interrupt. */
Fault hwrei();
@ -130,30 +169,31 @@ class SparcDynInst : public BaseDynInst<Impl>
// storage (which is pretty hard to imagine they would have reason
// to do).
uint64_t readIntReg(const StaticInst *si, int idx)
uint64_t readIntRegOperand(const StaticInst *si, int idx)
{
uint64_t val = this->cpu->readIntReg(this->_srcRegIdx[idx]);
DPRINTF(Sparc, "Reading int reg %d (%d, %d) as %x\n", (int)this->_flatSrcRegIdx[idx], (int)this->_srcRegIdx[idx], idx, val);
return this->cpu->readIntReg(this->_srcRegIdx[idx]);
}
TheISA::FloatReg readFloatReg(const StaticInst *si, int idx, int width)
TheISA::FloatReg readFloatRegOperand(const StaticInst *si,
int idx, int width)
{
return this->cpu->readFloatReg(this->_srcRegIdx[idx], width);
}
TheISA::FloatReg readFloatReg(const StaticInst *si, int idx)
TheISA::FloatReg readFloatRegOperand(const StaticInst *si, int idx)
{
return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
}
TheISA::FloatRegBits readFloatRegBits(const StaticInst *si,
TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si,
int idx, int width)
{
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx], width);
}
TheISA::FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
{
return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
}
@ -161,38 +201,38 @@ class SparcDynInst : public BaseDynInst<Impl>
/** @todo: Make results into arrays so they can handle multiple dest
* registers.
*/
void setIntReg(const StaticInst *si, int idx, uint64_t val)
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
{
DPRINTF(Sparc, "Setting int reg %d (%d, %d) to %x\n", (int)this->_flatDestRegIdx[idx], (int)this->_destRegIdx[idx], idx, val);
this->cpu->setIntReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setIntReg(si, idx, val);
BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
}
void setFloatReg(const StaticInst *si, int idx,
void setFloatRegOperand(const StaticInst *si, int idx,
TheISA::FloatReg val, int width)
{
this->cpu->setFloatReg(this->_destRegIdx[idx], val, width);
BaseDynInst<Impl>::setFloatReg(si, idx, val, width);
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width);
}
void setFloatReg(const StaticInst *si, int idx, TheISA::FloatReg val)
void setFloatRegOperand(const StaticInst *si, int idx, TheISA::FloatReg val)
{
this->cpu->setFloatReg(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setFloatReg(si, idx, val);
BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
}
void setFloatRegBits(const StaticInst *si, int idx,
void setFloatRegOperandBits(const StaticInst *si, int idx,
TheISA::FloatRegBits val, int width)
{
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val, width);
BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
void setFloatRegBits(const StaticInst *si,
void setFloatRegOperandBits(const StaticInst *si,
int idx, TheISA::FloatRegBits val)
{
this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
}
public:

View file

@ -303,6 +303,31 @@ class BaseSimpleCPU : public BaseCPU
return thread->setMiscRegWithEffect(misc_reg, val);
}
MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->readMiscReg(reg_idx);
}
MiscReg readMiscRegOperandWithEffect(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->readMiscRegWithEffect(reg_idx);
}
void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->setMiscReg(reg_idx, val);
}
void setMiscRegOperandWithEffect(
const StaticInst *si, int idx, const MiscReg &val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->setMiscRegWithEffect(reg_idx, val);
}
#if FULL_SYSTEM
Fault hwrei() { return thread->hwrei(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }