diff options
Diffstat (limited to 'src/arch/sparc/isa/base.isa')
-rw-r--r-- | src/arch/sparc/isa/base.isa | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa index bba63f407..4339003e0 100644 --- a/src/arch/sparc/isa/base.isa +++ b/src/arch/sparc/isa/base.isa @@ -154,6 +154,76 @@ def template ROrImmDecode {{ } }}; +output header {{ + union DoubleSingle + { + double d; + uint64_t ui; + uint32_t s[2]; + DoubleSingle(double _d) : d(_d) + {} + DoubleSingle(uint64_t _ui) : ui(_ui) + {} + DoubleSingle(uint32_t _s0, uint32_t _s1) + { + s[0] = _s0; + s[1] = _s1; + } + }; +}}; + +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 + return code +}}; + let {{ def splitOutImm(code): matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') |