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

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

