15094Sgblack@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan
22632Sstever@eecs.umich.edu// All rights reserved.
32632Sstever@eecs.umich.edu//
42632Sstever@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
52632Sstever@eecs.umich.edu// modification, are permitted provided that the following conditions are
62632Sstever@eecs.umich.edu// met: redistributions of source code must retain the above copyright
72632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
82632Sstever@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
92632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
102632Sstever@eecs.umich.edu// documentation and/or other materials provided with the distribution;
112632Sstever@eecs.umich.edu// neither the name of the copyright holders nor the names of its
122632Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from
132632Sstever@eecs.umich.edu// this software without specific prior written permission.
142632Sstever@eecs.umich.edu//
152632Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162632Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172632Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182632Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192632Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202632Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212632Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222632Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232632Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242632Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252632Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262632Sstever@eecs.umich.edu//
272632Sstever@eecs.umich.edu// Authors: Ali Saidi
282632Sstever@eecs.umich.edu//          Gabe Black
292632Sstever@eecs.umich.edu//          Steve Reinhardt
302632Sstever@eecs.umich.edu
312469SN/A////////////////////////////////////////////////////////////////////
322469SN/A//
332482SN/A// Privilege mode instructions
342469SN/A//
352469SN/A
363599Sgblack@eecs.umich.edudef template ControlRegConstructor {{
3712287Sgabeblack@google.com%(class_name)s::%(class_name)s(ExtMachInst machInst) :
3812287Sgabeblack@google.com        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, "%(reg_name)s")
3912287Sgabeblack@google.com{
4012287Sgabeblack@google.com    %(constructor)s;
4112287Sgabeblack@google.com}
422469SN/A}};
432469SN/A
442469SN/Adef template PrivExecute {{
4512287Sgabeblack@google.comFault
4612287Sgabeblack@google.com%(class_name)s::execute(ExecContext *xc, Trace::InstRecord *traceData) const
4712287Sgabeblack@google.com{
4812287Sgabeblack@google.com    %(op_decl)s;
4912287Sgabeblack@google.com    %(op_rd)s;
502469SN/A
5112287Sgabeblack@google.com    // If the processor isn't in privileged mode, fault out right away
5212287Sgabeblack@google.com    if (%(check)s)
5312287Sgabeblack@google.com        return std::make_shared<PrivilegedAction>();
542469SN/A
5512287Sgabeblack@google.com    %(tl_check)s
565094Sgblack@eecs.umich.edu
5712287Sgabeblack@google.com    Fault fault = NoFault;
5812287Sgabeblack@google.com    %(code)s;
5912287Sgabeblack@google.com    %(op_wb)s;
6012287Sgabeblack@google.com    return fault;
6112287Sgabeblack@google.com}
622469SN/A}};
632469SN/A
642526SN/Alet {{
6512287Sgabeblack@google.com    tl_check_code = '''
6612287Sgabeblack@google.com    if (Tl == 0)
6712287Sgabeblack@google.com        return std::make_shared<IllegalInstruction>();
6812287Sgabeblack@google.com'''
6912287Sgabeblack@google.com
7012287Sgabeblack@google.com    def doPrivFormat(code, check_code, name, Name, opt_flags, check_tl=False):
7112287Sgabeblack@google.com        (uses_imm, code, imm_code, r_string, i_string) = splitOutImm(code)
7212287Sgabeblack@google.com        tl_check = tl_check_code if check_tl else ''
7312287Sgabeblack@google.com        # If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
7412287Sgabeblack@google.com        # cut any other info out of the mnemonic. Also pick a different
7512287Sgabeblack@google.com        # base class.
7612287Sgabeblack@google.com        reg_base = 'Priv'
7712287Sgabeblack@google.com        reg_name = ''
783599Sgblack@eecs.umich.edu        for mnem in ["rdhpr", "rdpr", "rd"]:
793599Sgblack@eecs.umich.edu            if name.startswith(mnem):
8012287Sgabeblack@google.com                reg_name = name[len(mnem):]
813599Sgblack@eecs.umich.edu                name = mnem
8212287Sgabeblack@google.com                reg_base = 'RdPriv'
833599Sgblack@eecs.umich.edu                break
843599Sgblack@eecs.umich.edu        for mnem in ["wrhpr", "wrpr", "wr"]:
853599Sgblack@eecs.umich.edu            if name.startswith(mnem):
8612287Sgabeblack@google.com                reg_name = name[len(mnem):]
873599Sgblack@eecs.umich.edu                name = mnem
8812287Sgabeblack@google.com                reg_base = 'WrPriv'
893599Sgblack@eecs.umich.edu                break
9012287Sgabeblack@google.com        iop = InstObjParams(name, Name, reg_base,
9112287Sgabeblack@google.com                {"code": code, "check": check_code,
9212287Sgabeblack@google.com                 "tl_check": tl_check, "reg_name": reg_name},
933792Sgblack@eecs.umich.edu                opt_flags)
942469SN/A        header_output = BasicDeclare.subst(iop)
9512287Sgabeblack@google.com        if reg_name == '':
963599Sgblack@eecs.umich.edu            decoder_output = BasicConstructor.subst(iop)
973599Sgblack@eecs.umich.edu        else:
983599Sgblack@eecs.umich.edu            decoder_output = ControlRegConstructor.subst(iop)
992469SN/A        exec_output = PrivExecute.subst(iop)
10012287Sgabeblack@google.com        if uses_imm:
10112287Sgabeblack@google.com            imm_iop = InstObjParams(name, Name + 'Imm', reg_base + 'Imm',
10212287Sgabeblack@google.com                    {"code": imm_code, "check": check_code,
10312287Sgabeblack@google.com                     "tl_check": tl_check, "reg_name": reg_name},
1043792Sgblack@eecs.umich.edu                    opt_flags)
1052469SN/A            header_output += BasicDeclare.subst(imm_iop)
10612287Sgabeblack@google.com            if reg_name == '':
1073599Sgblack@eecs.umich.edu                decoder_output += BasicConstructor.subst(imm_iop)
1083599Sgblack@eecs.umich.edu            else:
1093599Sgblack@eecs.umich.edu                decoder_output += ControlRegConstructor.subst(imm_iop)
1102469SN/A            exec_output += PrivExecute.subst(imm_iop)
1112482SN/A            decode_block = ROrImmDecode.subst(iop)
1122469SN/A        else:
1132469SN/A            decode_block = BasicDecode.subst(iop)
1142526SN/A        return (header_output, decoder_output, exec_output, decode_block)
1152526SN/A}};
1162526SN/A
11712287Sgabeblack@google.comdef format Priv(code, extraCond=true, check_tl=false, *opt_flags) {{
11812287Sgabeblack@google.com    check_code = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
11912287Sgabeblack@google.com    (header_output, decoder_output, exec_output, decode_block) = \
12012287Sgabeblack@google.com            doPrivFormat(code, check_code, name, Name, opt_flags,
12112287Sgabeblack@google.com                         check_tl=(check_tl != 'false'))
1223587Sgblack@eecs.umich.edu}};
1233587Sgblack@eecs.umich.edu
12412287Sgabeblack@google.comdef format NoPriv(code, *opt_flags) {{
12512287Sgabeblack@google.com    # Instructions which use this format don't really check for any
12612287Sgabeblack@google.com    # particular mode, but the disassembly is performed using the control
12712287Sgabeblack@google.com    # register's actual name
12812287Sgabeblack@google.com    check_code = "false"
12912287Sgabeblack@google.com    (header_output, decoder_output, exec_output, decode_block) = \
13012287Sgabeblack@google.com            doPrivFormat(code, check_code, name, Name, opt_flags)
1313587Sgblack@eecs.umich.edu}};
1323587Sgblack@eecs.umich.edu
13312287Sgabeblack@google.comdef format HPriv(code, check_tl=false, *opt_flags) {{
13412287Sgabeblack@google.com    check_code = "!Hpstate.hpriv"
13512287Sgabeblack@google.com    (header_output, decoder_output, exec_output, decode_block) = \
13612287Sgabeblack@google.com            doPrivFormat(code, check_code, name, Name, opt_flags,
13712287Sgabeblack@google.com                         check_tl=(check_tl != 'false'))
1382469SN/A}};
1392469SN/A
140