| // 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. |
| // |
| // Authors: Ali Saidi |
| // Gabe Black |
| // Steve Reinhardt |
| |
| 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) |
| 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_]+)?') |
| 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") |
| orig_code = code |
| code = matcher.sub('Rs' + rString, orig_code) |
| imm_code = matcher.sub('imm', orig_code) |
| return (True, code, imm_code, rString, iString) |
| }}; |
| |
| 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>(); |
| } |
| }}; |
| |
| |