| // Copyright (c) 2006-2007 The Regents of The University of Michigan | |
| // All rights reserved. | |
| // | |
| // Redistribution and use in source and binary forms, with or without | |
| // modification, are permitted provided that the following conditions are | |
| // met: redistributions of source code must retain the above copyright | |
| // notice, this list of conditions and the following disclaimer; | |
| // redistributions in binary form must reproduce the above copyright | |
| // notice, this list of conditions and the following disclaimer in the | |
| // documentation and/or other materials provided with the distribution; | |
| // neither the name of the copyright holders nor the names of its | |
| // contributors may be used to endorse or promote products derived from | |
| // this software without specific prior written permission. | |
| // | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| def template ROrImmDecode {{ | |
| { | |
| return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) | |
| : (SparcStaticInst *)(new %(class_name)s(machInst))); | |
| } | |
| }}; | |
| 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) | |
| 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_]+)?') | |
| rOrImmMatch = matcher.search(code) | |
| if rOrImmMatch == None: | |
| return code, None, None | |
| orig_code = code | |
| 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 {{ | |
| /// Check "FP enabled" machine status bit. Called when executing any FP | |
| /// instruction. | |
| /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled | |
| /// if not. | |
| static inline Fault | |
| checkFpEnabled(PSTATE pstate, RegVal fprs) | |
| { | |
| if (pstate.pef && fprs & 0x4) { | |
| return NoFault; | |
| } else { | |
| return std::make_shared<FpDisabled>(); | |
| } | |
| } | |
| }}; | |