// 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>();
    }
}};


