# a defineInst() method that generates the code for an instruction
# definition.
-exportContextSymbols = ('InstObjParams', 'CodeBlock',
- 'makeList', 're', 'string')
+exportContextSymbols = ('InstObjParams', 'makeList', 're', 'string')
exportContext = {}
# 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
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
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:
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
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')
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
'\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'
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
// 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)
// 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':
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)
// 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)
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)
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)
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)
}};
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, LoadExecute,
+ decode_block) = doMemFormat(code, LoadFuncs,
AlternateAsiPrivFaultCheck, name, Name, opt_flags)
}};
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, StoreExecute,
+ decode_block) = doMemFormat(code, StoreFuncs,
AlternateAsiPrivFaultCheck, name, Name, 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) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- StoreExecute, '', name, Name, opt_flags)
+ StoreFuncs, '', name, Name, opt_flags)
}};
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(
}};
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)
}};
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;
}
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;
}
return fault;
}
+}};
+def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
}
return fault;
}
+}};
+def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
//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 = '''
//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,
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
}};
// 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)
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)
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)
}};
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)
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();
// 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]);
}
/** @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:
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); }