1 // Copyright (c) 2006 The Regents of The University of Michigan
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met: redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer;
8 // redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution;
11 // neither the name of the copyright holders nor the names of its
12 // contributors may be used to endorse or promote products derived from
13 // this software without specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ////////////////////////////////////////////////////////////////////
33 // Privilege mode instructions
38 * Base class for privelege mode operations.
40 class Priv : public SparcStaticInst
44 Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
45 SparcStaticInst(mnem, _machInst, __opClass)
49 std::string generateDisassembly(Addr pc,
50 const SymbolTable *symtab) const;
53 //This class is for instructions that explicitly read control
54 //registers. It provides a special generateDisassembly function.
55 class RdPriv : public Priv
59 RdPriv(const char *mnem, ExtMachInst _machInst,
60 OpClass __opClass, char const * _regName) :
61 Priv(mnem, _machInst, __opClass), regName(_regName)
65 std::string generateDisassembly(Addr pc,
66 const SymbolTable *symtab) const;
71 //This class is for instructions that explicitly write control
72 //registers. It provides a special generateDisassembly function.
73 class WrPriv : public Priv
77 WrPriv(const char *mnem, ExtMachInst _machInst,
78 OpClass __opClass, char const * _regName) :
79 Priv(mnem, _machInst, __opClass), regName(_regName)
83 std::string generateDisassembly(Addr pc,
84 const SymbolTable *symtab) const;
90 * Base class for privelege mode operations with immediates.
92 class PrivImm : public Priv
96 PrivImm(const char *mnem, ExtMachInst _machInst,
98 Priv(mnem, _machInst, __opClass), imm(SIMM13)
105 //This class is for instructions that explicitly write control
106 //registers. It provides a special generateDisassembly function.
107 class WrPrivImm : public PrivImm
111 WrPrivImm(const char *mnem, ExtMachInst _machInst,
112 OpClass __opClass, char const * _regName) :
113 PrivImm(mnem, _machInst, __opClass), regName(_regName)
117 std::string generateDisassembly(Addr pc,
118 const SymbolTable *symtab) const;
120 char const * regName;
125 std::string Priv::generateDisassembly(Addr pc,
126 const SymbolTable *symtab) const
128 std::stringstream response;
130 printMnemonic(response, mnemonic);
132 return response.str();
135 std::string RdPriv::generateDisassembly(Addr pc,
136 const SymbolTable *symtab) const
138 std::stringstream response;
140 printMnemonic(response, mnemonic);
142 ccprintf(response, " %%%s, ", regName);
143 printDestReg(response, 0);
145 return response.str();
148 std::string WrPriv::generateDisassembly(Addr pc,
149 const SymbolTable *symtab) const
151 std::stringstream response;
153 printMnemonic(response, mnemonic);
155 ccprintf(response, " ");
156 printSrcReg(response, 0);
157 ccprintf(response, ", ");
158 printSrcReg(response, 1);
159 ccprintf(response, ", %%%s", regName);
161 return response.str();
164 std::string WrPrivImm::generateDisassembly(Addr pc,
165 const SymbolTable *symtab) const
167 std::stringstream response;
169 printMnemonic(response, mnemonic);
171 ccprintf(response, " ");
172 printSrcReg(response, 0);
173 ccprintf(response, ", 0x%x, %%%s", imm, regName);
175 return response.str();
179 def template ControlRegConstructor {{
180 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
181 : %(base_class)s("%(mnemonic)s", machInst,
182 %(op_class)s, "%(reg_name)s")
188 def template PrivExecute {{
189 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
190 Trace::InstRecord *traceData) const
195 //If the processor isn't in privileged mode, fault out right away
197 return new PrivilegedAction;
199 Fault fault = NoFault;
207 def doPrivFormat(code, checkCode, name, Name, opt_flags):
208 (usesImm, code, immCode,
209 rString, iString) = splitOutImm(code)
210 #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
211 #cut any other info out of the mnemonic. Also pick a different
215 for mnem in ["rdhpr", "rdpr", "rd"]:
216 if name.startswith(mnem):
217 regName = name[len(mnem):]
221 for mnem in ["wrhpr", "wrpr", "wr"]:
222 if name.startswith(mnem):
223 regName = name[len(mnem):]
227 iop = InstObjParams(name, Name, regBase, code,
228 opt_flags, {"check": checkCode, "reg_name": regName})
229 header_output = BasicDeclare.subst(iop)
231 decoder_output = BasicConstructor.subst(iop)
233 decoder_output = ControlRegConstructor.subst(iop)
234 exec_output = PrivExecute.subst(iop)
236 imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
237 immCode, opt_flags, {"check": checkCode, "reg_name": regName})
238 header_output += BasicDeclare.subst(imm_iop)
240 decoder_output += BasicConstructor.subst(imm_iop)
242 decoder_output += ControlRegConstructor.subst(imm_iop)
243 exec_output += PrivExecute.subst(imm_iop)
244 decode_block = ROrImmDecode.subst(iop)
246 decode_block = BasicDecode.subst(iop)
247 return (header_output, decoder_output, exec_output, decode_block)
250 def format Priv(code, *opt_flags) {{
251 checkCode = "!(Pstate<2:> || Hpstate<2:>)"
252 (header_output, decoder_output,
253 exec_output, decode_block) = doPrivFormat(code,
254 checkCode, name, Name, opt_flags)
257 def format NoPriv(code, *opt_flags) {{
258 #Instructions which use this format don't really check for
259 #any particular mode, but the disassembly is performed
260 #using the control registers actual name
262 (header_output, decoder_output,
263 exec_output, decode_block) = doPrivFormat(code,
264 checkCode, name, Name, opt_flags)
267 def format PrivCheck(code, extraCheckCode, *opt_flags) {{
268 checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCheckCode
269 (header_output, decoder_output,
270 exec_output, decode_block) = doPrivFormat(code,
271 checkCode, name, Name, opt_flags)
274 def format HPriv(code, *opt_flags) {{
275 checkCode = "!Hpstate<2:2>"
276 (header_output, decoder_output,
277 exec_output, decode_block) = doPrivFormat(code,
278 checkCode, name, Name, opt_flags)