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


