--- /dev/null
+/*
+ * Copyright (c) 2006-2007 The Regents of The University of Michigan
+ * All rights reserved
+ * Copyright 2017 Google Inc.
+ *
+ * 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
+ */
+
+#include "arch/sparc/insts/priv.hh"
+
+namespace SparcISA
+{
+
+std::string
+Priv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ return response.str();
+}
+
+std::string
+RdPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ ccprintf(response, " %%%s, ", regName);
+ printDestReg(response, 0);
+
+ return response.str();
+}
+
+std::string
+WrPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ ccprintf(response, " ");
+ // If the first reg is %g0, don't print it.
+ // This improves readability
+ if (_srcRegIdx[0].index() != 0) {
+ printSrcReg(response, 0);
+ ccprintf(response, ", ");
+ }
+ printSrcReg(response, 1);
+ ccprintf(response, ", %%%s", regName);
+
+ return response.str();
+}
+
+std::string
+WrPrivImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ ccprintf(response, " ");
+ // If the first reg is %g0, don't print it.
+ // This improves readability
+ if (_srcRegIdx[0].index() != 0) {
+ printSrcReg(response, 0);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "%#x, %%%s", imm, regName);
+
+ return response.str();
+}
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2006-2007 The Regents of The University of Michigan
+ * All rights reserved
+ * Copyright 2017 Google Inc.
+ *
+ * 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
+ */
+
+#ifndef __ARCH_SPARC_INSTS_PRIV_HH__
+#define __ARCH_SPARC_INSTS_PRIV_HH__
+
+#include "arch/sparc/insts/static_inst.hh"
+
+namespace SparcISA
+{
+
+/**
+ * Base class for privelege mode operations.
+ */
+class Priv : public SparcStaticInst
+{
+ protected:
+ using SparcStaticInst::SparcStaticInst;
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class PrivReg : public Priv
+{
+ protected:
+ PrivReg(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, char const * _regName) :
+ Priv(mnem, _machInst, __opClass), regName(_regName)
+ {}
+
+ char const *regName;
+};
+
+// This class is for instructions that explicitly read control
+// registers. It provides a special generateDisassembly function.
+class RdPriv : public PrivReg
+{
+ protected:
+ using PrivReg::PrivReg;
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+// This class is for instructions that explicitly write control
+// registers. It provides a special generateDisassembly function.
+class WrPriv : public PrivReg
+{
+ protected:
+ using PrivReg::PrivReg;
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for privelege mode operations with immediates.
+ */
+class PrivImm : public Priv
+{
+ protected:
+ // Constructor
+ PrivImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ Priv(mnem, _machInst, __opClass), imm(bits(_machInst, 12, 0))
+ {}
+
+ int32_t imm;
+};
+
+// This class is for instructions that explicitly write control
+// registers. It provides a special generateDisassembly function.
+class WrPrivImm : public PrivImm
+{
+ protected:
+ // Constructor
+ WrPrivImm(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, char const *_regName) :
+ PrivImm(mnem, _machInst, __opClass), regName(_regName)
+ {}
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ char const *regName;
+}
+;
+}
+
+#endif //__ARCH_SPARC_INSTS_PRIV_HH__
}
0x29: decode RS1 {
0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}});
- 0x01: HPriv::rdhprhtstate({{Rd = Htstate;}}, checkTl=true);
+ 0x01: HPriv::rdhprhtstate({{Rd = Htstate;}}, check_tl=true);
// 0x02 should cause an illegal instruction exception
0x03: HPriv::rdhprhintp({{Rd = Hintp;}});
// 0x04 should cause an illegal instruction exception
0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}});
}
0x2A: decode RS1 {
- 0x00: Priv::rdprtpc({{Rd = Tpc;}}, checkTl=true);
- 0x01: Priv::rdprtnpc({{Rd = Tnpc;}}, checkTl=true);
- 0x02: Priv::rdprtstate({{Rd = Tstate;}}, checkTl=true);
- 0x03: Priv::rdprtt({{Rd = Tt;}}, checkTl=true);
+ 0x00: Priv::rdprtpc({{Rd = Tpc;}}, check_tl=true);
+ 0x01: Priv::rdprtnpc({{Rd = Tnpc;}}, check_tl=true);
+ 0x02: Priv::rdprtstate({{Rd = Tstate;}}, check_tl=true);
+ 0x03: Priv::rdprtt({{Rd = Tt;}}, check_tl=true);
0x04: Priv::rdprtick({{Rd = Tick;}});
0x05: Priv::rdprtba({{Rd = Tba;}});
0x06: Priv::rdprpstate({{Rd = Pstate;}});
0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}});
// 0x01 should cause an illegal instruction exception
0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
- 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}, false,
+ 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}},
IsSquashAfter);
// 0x04-0x05 should cause an illegal instruction exception
0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}});
}
0x32: decode RD {
0x00: Priv::wrprtpc(
- {{Tpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
+ {{Tpc = Rs1 ^ Rs2_or_imm13;}}, check_tl=true);
0x01: Priv::wrprtnpc(
- {{Tnpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
+ {{Tnpc = Rs1 ^ Rs2_or_imm13;}}, check_tl=true);
0x02: Priv::wrprtstate(
- {{Tstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
+ {{Tstate = Rs1 ^ Rs2_or_imm13;}}, check_tl=true);
0x03: Priv::wrprtt(
- {{Tt = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
+ {{Tt = Rs1 ^ Rs2_or_imm13;}}, check_tl=true);
0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
0x33: decode RD {
0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}});
0x01: HPriv::wrhprhtstate(
- {{Htstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
+ {{Htstate = Rs1 ^ Rs2_or_imm13;}}, check_tl=true);
// 0x02 should cause an illegal instruction exception
0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}});
// 0x04 should cause an illegal instruction exception
NPC = Tnpc;
NNPC = Tnpc + 4;
Tl = Tl - 1;
- }}, checkTl=true);
+ }}, check_tl=true);
0x1: Priv::retry({{
Cwp = Tstate<4:0>;
Pstate = Tstate<20:8>;
NPC = Tpc;
NNPC = Tnpc;
Tl = Tl - 1;
- }}, checkTl=true);
+ }}, check_tl=true);
}
}
}
// Privilege mode instructions
//
-output header {{
- /**
- * Base class for privelege mode operations.
- */
- class Priv : public SparcStaticInst
- {
- protected:
- // Constructor
- Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- SparcStaticInst(mnem, _machInst, __opClass)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-
- // This class is for instructions that explicitly read control
- // registers. It provides a special generateDisassembly function.
- class RdPriv : public Priv
- {
- protected:
- // Constructor
- RdPriv(const char *mnem, ExtMachInst _machInst,
- OpClass __opClass, char const * _regName) :
- Priv(mnem, _machInst, __opClass), regName(_regName)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- char const * regName;
- };
-
- // This class is for instructions that explicitly write control
- // registers. It provides a special generateDisassembly function.
- class WrPriv : public Priv
- {
- protected:
- // Constructor
- WrPriv(const char *mnem, ExtMachInst _machInst,
- OpClass __opClass, char const * _regName) :
- Priv(mnem, _machInst, __opClass), regName(_regName)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- char const * regName;
- };
-
- /**
- * Base class for privelege mode operations with immediates.
- */
- class PrivImm : public Priv
- {
- protected:
- // Constructor
- PrivImm(const char *mnem, ExtMachInst _machInst,
- OpClass __opClass) :
- Priv(mnem, _machInst, __opClass), imm(SIMM13)
- {
- }
-
- int32_t imm;
- };
-
- // This class is for instructions that explicitly write control
- // registers. It provides a special generateDisassembly function.
- class WrPrivImm : public PrivImm
- {
- protected:
- // Constructor
- WrPrivImm(const char *mnem, ExtMachInst _machInst,
- OpClass __opClass, char const * _regName) :
- PrivImm(mnem, _machInst, __opClass), regName(_regName)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- char const * regName;
- };
-}};
-
-output decoder {{
- std::string
- Priv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, mnemonic);
-
- return response.str();
- }
-
- std::string
- RdPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, mnemonic);
-
- ccprintf(response, " %%%s, ", regName);
- printDestReg(response, 0);
-
- return response.str();
- }
-
- std::string
- WrPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, mnemonic);
-
- ccprintf(response, " ");
- // If the first reg is %g0, don't print it.
- // This improves readability
- if (_srcRegIdx[0].index() != 0) {
- printSrcReg(response, 0);
- ccprintf(response, ", ");
- }
- printSrcReg(response, 1);
- ccprintf(response, ", %%%s", regName);
-
- return response.str();
- }
-
- std::string WrPrivImm::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, mnemonic);
-
- ccprintf(response, " ");
- // If the first reg is %g0, don't print it.
- // This improves readability
- if (_srcRegIdx[0].index() != 0) {
- printSrcReg(response, 0);
- ccprintf(response, ", ");
- }
- ccprintf(response, "0x%x, %%%s", imm, regName);
-
- return response.str();
- }
-}};
-
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;
- }
+%(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>();
-
- if (%(tlCheck)s)
- return std::make_shared<IllegalInstruction>();
-
- Fault fault = NoFault;
- %(code)s;
- %(op_wb)s;
- return fault;
- }
+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 {{
- def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags):
- (usesImm, code, immCode,
- rString, iString) = splitOutImm(code)
- #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.
- regBase = 'Priv'
- regName = ''
+ 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):
- regName = name[len(mnem):]
+ reg_name = name[len(mnem):]
name = mnem
- regBase = 'RdPriv'
+ reg_base = 'RdPriv'
break
for mnem in ["wrhpr", "wrpr", "wr"]:
if name.startswith(mnem):
- regName = name[len(mnem):]
+ reg_name = name[len(mnem):]
name = mnem
- regBase = 'WrPriv'
+ reg_base = 'WrPriv'
break
- iop = InstObjParams(name, Name, regBase,
- {"code": code, "check": checkCode,
- "tlCheck": tlCheck, "reg_name": regName},
+ 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 regName == '':
+ if reg_name == '':
decoder_output = BasicConstructor.subst(iop)
else:
decoder_output = ControlRegConstructor.subst(iop)
exec_output = PrivExecute.subst(iop)
- if usesImm:
- imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
- {"code": immCode, "check": checkCode,
- "tlCheck": tlCheck, "reg_name": regName},
+ 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 regName == '':
+ if reg_name == '':
decoder_output += BasicConstructor.subst(imm_iop)
else:
decoder_output += ControlRegConstructor.subst(imm_iop)
return (header_output, decoder_output, exec_output, decode_block)
}};
-def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{
- checkCode = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
- if checkTl != "false":
- tlCheck = "Tl == 0"
- else:
- tlCheck = "false"
- (header_output, decoder_output,
- exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, tlCheck, opt_flags)
+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, checkTl=false, *opt_flags) {{
- #Instructions which use this format don't really check for
- #any particular mode, but the disassembly is performed
- #using the control registers actual name
- checkCode = "false"
- if checkTl != "false":
- tlCheck = "Tl == 0"
- else:
- tlCheck = "false"
- (header_output, decoder_output,
- exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, tlCheck, opt_flags)
+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, checkTl=false, *opt_flags) {{
- checkCode = "!Hpstate.hpriv"
- if checkTl != "false":
- tlCheck = "Tl == 0"
- else:
- tlCheck = "false"
- (header_output, decoder_output,
- exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, tlCheck, 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'))
}};