| // 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. Non-full-system mode: always returns NoFault. |
| static inline Fault |
| checkFpEnableFault(ExecContext *xc) |
| { |
| if (FullSystem) { |
| PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE); |
| if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) { |
| return NoFault; |
| } else { |
| return std::make_shared<FpDisabled>(); |
| } |
| } else { |
| return NoFault; |
| } |
| } |
| |
| static inline Fault |
| checkVecEnableFault(ExecContext *xc) |
| { |
| return std::make_shared<VecDisabled>(); |
| } |
| }}; |
| |
| |