sparc: Clean up some code in base.isa.
This includes the filterDoubles function which adds code to combine 32 bit values into doubles or 64 bit values for floating point, and the splitOutImm function which detects if the code that implements an instruction has a register and immediate variant, and generates code for each. Change-Id: I5524b9acd6e610b51fd91fe70276c34c23be9f85 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35235 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -52,69 +52,69 @@ output header {{
|
||||
let {{
|
||||
def filterDoubles(code):
|
||||
assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
|
||||
for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
|
||||
next_pos = 0
|
||||
operandsREString = (r'''
|
||||
(?<!\w) # neg. lookbehind assertion: prevent partial matches
|
||||
((%s)(?:_([^\W_]+))?) # match: operand with optional '.' then suffix
|
||||
(?!\w) # neg. lookahead assertion: prevent partial matches
|
||||
''' % opName)
|
||||
operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
|
||||
is_src = False
|
||||
is_dest = False
|
||||
extension = None
|
||||
foundOne = False
|
||||
while 1:
|
||||
match = operandsRE.search(code, next_pos)
|
||||
if not match:
|
||||
break
|
||||
foundOne = True
|
||||
op = match.groups()
|
||||
(op_full, op_base, op_ext) = op
|
||||
is_dest_local = (assignRE.match(code, match.end()) != None)
|
||||
is_dest = is_dest or is_dest_local
|
||||
is_src = is_src or not is_dest_local
|
||||
if extension and extension != op_ext:
|
||||
raise Exception("Inconsistent extensions in double filter")
|
||||
extension = op_ext
|
||||
next_pos = match.end()
|
||||
if foundOne:
|
||||
# Get rid of any unwanted extension
|
||||
code = operandsRE.sub(op_base, code)
|
||||
is_int = False
|
||||
member = "d"
|
||||
if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
|
||||
is_int = True
|
||||
member = "ui"
|
||||
if is_src:
|
||||
code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
|
||||
(opName, opName, opName, member)) + code
|
||||
if is_dest:
|
||||
code += '''
|
||||
%s_low = DoubleSingle(%s).s[1];
|
||||
%s_high = DoubleSingle(%s).s[0];''' % \
|
||||
(opName, opName, opName, opName)
|
||||
if is_int:
|
||||
code = ("uint64_t %s;" % opName) + code
|
||||
else:
|
||||
code = ("double %s;" % opName) + code
|
||||
|
||||
int_extensions = ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw")
|
||||
operand_names = ("Frd", "Frs1", "Frs2", "Frd_N")
|
||||
|
||||
class Operand(object):
|
||||
def __init__(self, name, ext):
|
||||
self.name = name
|
||||
self.ext = ext
|
||||
self.src = False
|
||||
self.dest = False
|
||||
|
||||
operands = {}
|
||||
|
||||
operandsREString = (r'''
|
||||
# neg. lookbehind assertion: prevent partial matches
|
||||
(?<!\w)
|
||||
# match: operand with optional '.' then suffix
|
||||
((?P<name>%s)(_(?P<ext>[^\W_]+))?)
|
||||
# neg. lookahead assertion: prevent partial matches
|
||||
(?!\w)
|
||||
''' % '|'.join(operand_names))
|
||||
operandsRE = re.compile(operandsREString, re.MULTILINE | re.VERBOSE)
|
||||
|
||||
for match in operandsRE.finditer(code):
|
||||
name = match.group('name')
|
||||
ext = match.group('ext')
|
||||
operand = operands.setdefault(name, Operand(name, ext))
|
||||
if assignRE.match(code, match.end()):
|
||||
operand.dest = True
|
||||
else:
|
||||
operand.src = True
|
||||
if operand.ext != ext:
|
||||
raise Exception("Inconsistent extensions in double filter")
|
||||
|
||||
# Get rid of any unwanted extension
|
||||
code = operandsRE.sub('\g<name>', code)
|
||||
|
||||
for op in operands.values():
|
||||
is_int = op.ext in int_extensions
|
||||
member, type = ('ui', 'uint64_t') if is_int else ('d', 'double')
|
||||
if op.src:
|
||||
code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
|
||||
(op.name, op.name, op.name, member)) + code
|
||||
if op.dest:
|
||||
code += '''
|
||||
%s_low = DoubleSingle(%s).s[1];
|
||||
%s_high = DoubleSingle(%s).s[0];''' % \
|
||||
(op.name, op.name, op.name, op.name)
|
||||
code = ("%s %s;" % (type, op.name)) + code
|
||||
return code
|
||||
}};
|
||||
|
||||
let {{
|
||||
def splitOutImm(code):
|
||||
matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
|
||||
matcher = re.compile(
|
||||
r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
|
||||
rOrImmMatch = matcher.search(code)
|
||||
if (rOrImmMatch == None):
|
||||
return (False, code, '', '', '')
|
||||
rString = rOrImmMatch.group("rNum")
|
||||
if (rOrImmMatch.group("typeQual") != None):
|
||||
rString += rOrImmMatch.group("typeQual")
|
||||
iString = rOrImmMatch.group("iNum")
|
||||
if rOrImmMatch == None:
|
||||
return code, None, None
|
||||
orig_code = code
|
||||
code = matcher.sub('Rs' + rString, orig_code)
|
||||
imm_code = matcher.sub('imm', orig_code)
|
||||
return (True, code, imm_code, rString, iString)
|
||||
reg_code = matcher.sub('Rs\g<rNum>\g<typeQual>', code)
|
||||
imm_code = matcher.sub('imm', code)
|
||||
return reg_code, imm_code, rOrImmMatch.group('iNum')
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
|
||||
@@ -86,13 +86,12 @@ def template BranchDecode {{
|
||||
// Primary format for branch instructions:
|
||||
def format Branch(code, *opt_flags) {{
|
||||
code = 'NNPC = NNPC;\n' + code
|
||||
(usesImm, code, immCode,
|
||||
rString, iString) = splitOutImm(code)
|
||||
code, immCode, iString = splitOutImm(code)
|
||||
iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
exec_output = JumpExecute.subst(iop)
|
||||
if usesImm:
|
||||
if immCode is not None:
|
||||
imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
|
||||
immCode, opt_flags)
|
||||
header_output += BasicDeclare.subst(imm_iop)
|
||||
|
||||
@@ -59,15 +59,14 @@ def template IntOpExecute {{
|
||||
|
||||
let {{
|
||||
def doIntFormat(code, ccCode, name, Name, opt_flags):
|
||||
(usesImm, code, immCode,
|
||||
rString, iString) = splitOutImm(code)
|
||||
code, immCode, iString = splitOutImm(code)
|
||||
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:
|
||||
if immCode is not None:
|
||||
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
|
||||
{"code": immCode, "cc_code": ccCode}, opt_flags)
|
||||
header_output += BasicDeclare.subst(imm_iop)
|
||||
|
||||
@@ -64,7 +64,7 @@ let {{
|
||||
'''
|
||||
|
||||
def doPrivFormat(code, check_code, name, Name, opt_flags, check_tl=False):
|
||||
(uses_imm, code, imm_code, r_string, i_string) = splitOutImm(code)
|
||||
code, imm_code, _ = splitOutImm(code)
|
||||
tl_check = tl_check_code if check_tl else ''
|
||||
# If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
|
||||
# cut any other info out of the mnemonic. Also pick a different
|
||||
@@ -93,7 +93,7 @@ let {{
|
||||
else:
|
||||
decoder_output = ControlRegConstructor.subst(iop)
|
||||
exec_output = PrivExecute.subst(iop)
|
||||
if uses_imm:
|
||||
if imm_code is not None:
|
||||
imm_iop = InstObjParams(name, Name + 'Imm', reg_base + 'Imm',
|
||||
{"code": imm_code, "check": check_code,
|
||||
"tl_check": tl_check, "reg_name": reg_name},
|
||||
|
||||
Reference in New Issue
Block a user