// 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.

////////////////////////////////////////////////////////////////////
//
// Privilege mode instructions
//

def template ControlRegConstructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, "%(reg_name)s")
{
    %(constructor)s;
}
}};

def template PrivExecute {{
Fault
%(class_name)s::execute(ExecContext *xc, Trace::InstRecord *traceData) const
{
    %(op_decl)s;
    %(op_rd)s;

    // If the processor isn't in privileged mode, fault out right away
    if (%(check)s)
        return std::make_shared<PrivilegedAction>();

    %(tl_check)s

    Fault fault = NoFault;
    %(code)s;
    %(op_wb)s;
    return fault;
}
}};

let {{
    tl_check_code = '''
    if (Tl == 0)
        return std::make_shared<IllegalInstruction>();
'''

    def doPrivFormat(code, check_code, name, Name, opt_flags, check_tl=False):
        (uses_imm, code, imm_code, r_string, i_string) = splitOutImm(code)
        tl_check = tl_check_code if check_tl else ''
        # If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
        # cut any other info out of the mnemonic. Also pick a different
        # base class.
        reg_base = 'Priv'
        reg_name = ''
        for mnem in ["rdhpr", "rdpr", "rd"]:
            if name.startswith(mnem):
                reg_name = name[len(mnem):]
                name = mnem
                reg_base = 'RdPriv'
                break
        for mnem in ["wrhpr", "wrpr", "wr"]:
            if name.startswith(mnem):
                reg_name = name[len(mnem):]
                name = mnem
                reg_base = 'WrPriv'
                break
        iop = InstObjParams(name, Name, reg_base,
                {"code": code, "check": check_code,
                 "tl_check": tl_check, "reg_name": reg_name},
                opt_flags)
        header_output = BasicDeclare.subst(iop)
        if reg_name == '':
            decoder_output = BasicConstructor.subst(iop)
        else:
            decoder_output = ControlRegConstructor.subst(iop)
        exec_output = PrivExecute.subst(iop)
        if uses_imm:
            imm_iop = InstObjParams(name, Name + 'Imm', reg_base + 'Imm',
                    {"code": imm_code, "check": check_code,
                     "tl_check": tl_check, "reg_name": reg_name},
                    opt_flags)
            header_output += BasicDeclare.subst(imm_iop)
            if reg_name == '':
                decoder_output += BasicConstructor.subst(imm_iop)
            else:
                decoder_output += ControlRegConstructor.subst(imm_iop)
            exec_output += PrivExecute.subst(imm_iop)
            decode_block = ROrImmDecode.subst(iop)
        else:
            decode_block = BasicDecode.subst(iop)
        return (header_output, decoder_output, exec_output, decode_block)
}};

def format Priv(code, extraCond=true, check_tl=false, *opt_flags) {{
    check_code = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
    (header_output, decoder_output, exec_output, decode_block) = \
            doPrivFormat(code, check_code, name, Name, opt_flags,
                         check_tl=(check_tl != 'false'))
}};

def format NoPriv(code, *opt_flags) {{
    # Instructions which use this format don't really check for any
    # particular mode, but the disassembly is performed using the control
    # register's actual name
    check_code = "false"
    (header_output, decoder_output, exec_output, decode_block) = \
            doPrivFormat(code, check_code, name, Name, opt_flags)
}};

def format HPriv(code, check_tl=false, *opt_flags) {{
    check_code = "!Hpstate.hpriv"
    (header_output, decoder_output, exec_output, decode_block) = \
            doPrivFormat(code, check_code, name, Name, opt_flags,
                         check_tl=(check_tl != 'false'))
}};

