// 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")
{
    %(set_reg_idx_arr)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):
        code, imm_code, _ = 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 imm_code is not None:
            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'))
}};

