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:
Gabe Black
2020-09-27 23:41:02 -07:00
parent 8041ab0ad7
commit cda1221dd4
4 changed files with 62 additions and 64 deletions

View File

@@ -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 {{

View File

@@ -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)

View File

@@ -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)

View File

@@ -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},