priv.isa (3792:dae368e56d0e) priv.isa (5094:10b8551e3e3f)
1// Copyright (c) 2006 The Regents of The University of Michigan
1// Copyright (c) 2006-2007 The Regents of The University of Michigan
2// All rights reserved.
3//
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.
14//
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.
26//
27// Authors: Ali Saidi
28// Gabe Black
29// Steve Reinhardt
30
31////////////////////////////////////////////////////////////////////
32//
33// Privilege mode instructions
34//
35
36output header {{
37 /**
38 * Base class for privelege mode operations.
39 */
40 class Priv : public SparcStaticInst
41 {
42 protected:
43 // Constructor
44 Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
45 SparcStaticInst(mnem, _machInst, __opClass)
46 {
47 }
48
49 std::string generateDisassembly(Addr pc,
50 const SymbolTable *symtab) const;
51 };
52
53 //This class is for instructions that explicitly read control
54 //registers. It provides a special generateDisassembly function.
55 class RdPriv : public Priv
56 {
57 protected:
58 //Constructor
59 RdPriv(const char *mnem, ExtMachInst _machInst,
60 OpClass __opClass, char const * _regName) :
61 Priv(mnem, _machInst, __opClass), regName(_regName)
62 {
63 }
64
65 std::string generateDisassembly(Addr pc,
66 const SymbolTable *symtab) const;
67
68 char const * regName;
69 };
70
71 //This class is for instructions that explicitly write control
72 //registers. It provides a special generateDisassembly function.
73 class WrPriv : public Priv
74 {
75 protected:
76 //Constructor
77 WrPriv(const char *mnem, ExtMachInst _machInst,
78 OpClass __opClass, char const * _regName) :
79 Priv(mnem, _machInst, __opClass), regName(_regName)
80 {
81 }
82
83 std::string generateDisassembly(Addr pc,
84 const SymbolTable *symtab) const;
85
86 char const * regName;
87 };
88
89 /**
90 * Base class for privelege mode operations with immediates.
91 */
92 class PrivImm : public Priv
93 {
94 protected:
95 // Constructor
96 PrivImm(const char *mnem, ExtMachInst _machInst,
97 OpClass __opClass) :
98 Priv(mnem, _machInst, __opClass), imm(SIMM13)
99 {
100 }
101
102 int32_t imm;
103 };
104
105 //This class is for instructions that explicitly write control
106 //registers. It provides a special generateDisassembly function.
107 class WrPrivImm : public PrivImm
108 {
109 protected:
110 //Constructor
111 WrPrivImm(const char *mnem, ExtMachInst _machInst,
112 OpClass __opClass, char const * _regName) :
113 PrivImm(mnem, _machInst, __opClass), regName(_regName)
114 {
115 }
116
117 std::string generateDisassembly(Addr pc,
118 const SymbolTable *symtab) const;
119
120 char const * regName;
121 };
122}};
123
124output decoder {{
125 std::string Priv::generateDisassembly(Addr pc,
126 const SymbolTable *symtab) const
127 {
128 std::stringstream response;
129
130 printMnemonic(response, mnemonic);
131
132 return response.str();
133 }
134
135 std::string RdPriv::generateDisassembly(Addr pc,
136 const SymbolTable *symtab) const
137 {
138 std::stringstream response;
139
140 printMnemonic(response, mnemonic);
141
142 ccprintf(response, " %%%s, ", regName);
143 printDestReg(response, 0);
144
145 return response.str();
146 }
147
148 std::string WrPriv::generateDisassembly(Addr pc,
149 const SymbolTable *symtab) const
150 {
151 std::stringstream response;
152
153 printMnemonic(response, mnemonic);
154
155 ccprintf(response, " ");
156 //If the first reg is %g0, don't print it.
157 //This improves readability
158 if(_srcRegIdx[0] != 0)
159 {
160 printSrcReg(response, 0);
161 ccprintf(response, ", ");
162 }
163 printSrcReg(response, 1);
164 ccprintf(response, ", %%%s", regName);
165
166 return response.str();
167 }
168
169 std::string WrPrivImm::generateDisassembly(Addr pc,
170 const SymbolTable *symtab) const
171 {
172 std::stringstream response;
173
174 printMnemonic(response, mnemonic);
175
176 ccprintf(response, " ");
177 //If the first reg is %g0, don't print it.
178 //This improves readability
179 if(_srcRegIdx[0] != 0)
180 {
181 printSrcReg(response, 0);
182 ccprintf(response, ", ");
183 }
184 ccprintf(response, "0x%x, %%%s", imm, regName);
185
186 return response.str();
187 }
188}};
189
190def template ControlRegConstructor {{
191 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
192 : %(base_class)s("%(mnemonic)s", machInst,
193 %(op_class)s, "%(reg_name)s")
194 {
195 %(constructor)s;
196 }
197}};
198
199def template PrivExecute {{
200 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
201 Trace::InstRecord *traceData) const
202 {
203 %(op_decl)s;
204 %(op_rd)s;
205
206 //If the processor isn't in privileged mode, fault out right away
207 if(%(check)s)
208 return new PrivilegedAction;
209
2// All rights reserved.
3//
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.
14//
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.
26//
27// Authors: Ali Saidi
28// Gabe Black
29// Steve Reinhardt
30
31////////////////////////////////////////////////////////////////////
32//
33// Privilege mode instructions
34//
35
36output header {{
37 /**
38 * Base class for privelege mode operations.
39 */
40 class Priv : public SparcStaticInst
41 {
42 protected:
43 // Constructor
44 Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
45 SparcStaticInst(mnem, _machInst, __opClass)
46 {
47 }
48
49 std::string generateDisassembly(Addr pc,
50 const SymbolTable *symtab) const;
51 };
52
53 //This class is for instructions that explicitly read control
54 //registers. It provides a special generateDisassembly function.
55 class RdPriv : public Priv
56 {
57 protected:
58 //Constructor
59 RdPriv(const char *mnem, ExtMachInst _machInst,
60 OpClass __opClass, char const * _regName) :
61 Priv(mnem, _machInst, __opClass), regName(_regName)
62 {
63 }
64
65 std::string generateDisassembly(Addr pc,
66 const SymbolTable *symtab) const;
67
68 char const * regName;
69 };
70
71 //This class is for instructions that explicitly write control
72 //registers. It provides a special generateDisassembly function.
73 class WrPriv : public Priv
74 {
75 protected:
76 //Constructor
77 WrPriv(const char *mnem, ExtMachInst _machInst,
78 OpClass __opClass, char const * _regName) :
79 Priv(mnem, _machInst, __opClass), regName(_regName)
80 {
81 }
82
83 std::string generateDisassembly(Addr pc,
84 const SymbolTable *symtab) const;
85
86 char const * regName;
87 };
88
89 /**
90 * Base class for privelege mode operations with immediates.
91 */
92 class PrivImm : public Priv
93 {
94 protected:
95 // Constructor
96 PrivImm(const char *mnem, ExtMachInst _machInst,
97 OpClass __opClass) :
98 Priv(mnem, _machInst, __opClass), imm(SIMM13)
99 {
100 }
101
102 int32_t imm;
103 };
104
105 //This class is for instructions that explicitly write control
106 //registers. It provides a special generateDisassembly function.
107 class WrPrivImm : public PrivImm
108 {
109 protected:
110 //Constructor
111 WrPrivImm(const char *mnem, ExtMachInst _machInst,
112 OpClass __opClass, char const * _regName) :
113 PrivImm(mnem, _machInst, __opClass), regName(_regName)
114 {
115 }
116
117 std::string generateDisassembly(Addr pc,
118 const SymbolTable *symtab) const;
119
120 char const * regName;
121 };
122}};
123
124output decoder {{
125 std::string Priv::generateDisassembly(Addr pc,
126 const SymbolTable *symtab) const
127 {
128 std::stringstream response;
129
130 printMnemonic(response, mnemonic);
131
132 return response.str();
133 }
134
135 std::string RdPriv::generateDisassembly(Addr pc,
136 const SymbolTable *symtab) const
137 {
138 std::stringstream response;
139
140 printMnemonic(response, mnemonic);
141
142 ccprintf(response, " %%%s, ", regName);
143 printDestReg(response, 0);
144
145 return response.str();
146 }
147
148 std::string WrPriv::generateDisassembly(Addr pc,
149 const SymbolTable *symtab) const
150 {
151 std::stringstream response;
152
153 printMnemonic(response, mnemonic);
154
155 ccprintf(response, " ");
156 //If the first reg is %g0, don't print it.
157 //This improves readability
158 if(_srcRegIdx[0] != 0)
159 {
160 printSrcReg(response, 0);
161 ccprintf(response, ", ");
162 }
163 printSrcReg(response, 1);
164 ccprintf(response, ", %%%s", regName);
165
166 return response.str();
167 }
168
169 std::string WrPrivImm::generateDisassembly(Addr pc,
170 const SymbolTable *symtab) const
171 {
172 std::stringstream response;
173
174 printMnemonic(response, mnemonic);
175
176 ccprintf(response, " ");
177 //If the first reg is %g0, don't print it.
178 //This improves readability
179 if(_srcRegIdx[0] != 0)
180 {
181 printSrcReg(response, 0);
182 ccprintf(response, ", ");
183 }
184 ccprintf(response, "0x%x, %%%s", imm, regName);
185
186 return response.str();
187 }
188}};
189
190def template ControlRegConstructor {{
191 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
192 : %(base_class)s("%(mnemonic)s", machInst,
193 %(op_class)s, "%(reg_name)s")
194 {
195 %(constructor)s;
196 }
197}};
198
199def template PrivExecute {{
200 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
201 Trace::InstRecord *traceData) const
202 {
203 %(op_decl)s;
204 %(op_rd)s;
205
206 //If the processor isn't in privileged mode, fault out right away
207 if(%(check)s)
208 return new PrivilegedAction;
209
210 if(%(tlCheck)s)
211 return new IllegalInstruction;
212
210 Fault fault = NoFault;
211 %(code)s;
212 %(op_wb)s;
213 return fault;
214 }
215}};
216
217let {{
213 Fault fault = NoFault;
214 %(code)s;
215 %(op_wb)s;
216 return fault;
217 }
218}};
219
220let {{
218 def doPrivFormat(code, checkCode, name, Name, opt_flags):
221 def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags):
219 (usesImm, code, immCode,
220 rString, iString) = splitOutImm(code)
221 #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
222 #cut any other info out of the mnemonic. Also pick a different
223 #base class.
224 regBase = 'Priv'
225 regName = ''
226 for mnem in ["rdhpr", "rdpr", "rd"]:
227 if name.startswith(mnem):
228 regName = name[len(mnem):]
229 name = mnem
230 regBase = 'RdPriv'
231 break
232 for mnem in ["wrhpr", "wrpr", "wr"]:
233 if name.startswith(mnem):
234 regName = name[len(mnem):]
235 name = mnem
236 regBase = 'WrPriv'
237 break
238 iop = InstObjParams(name, Name, regBase,
222 (usesImm, code, immCode,
223 rString, iString) = splitOutImm(code)
224 #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
225 #cut any other info out of the mnemonic. Also pick a different
226 #base class.
227 regBase = 'Priv'
228 regName = ''
229 for mnem in ["rdhpr", "rdpr", "rd"]:
230 if name.startswith(mnem):
231 regName = name[len(mnem):]
232 name = mnem
233 regBase = 'RdPriv'
234 break
235 for mnem in ["wrhpr", "wrpr", "wr"]:
236 if name.startswith(mnem):
237 regName = name[len(mnem):]
238 name = mnem
239 regBase = 'WrPriv'
240 break
241 iop = InstObjParams(name, Name, regBase,
239 {"code": code, "check": checkCode, "reg_name": regName},
242 {"code": code, "check": checkCode,
243 "tlCheck": tlCheck, "reg_name": regName},
240 opt_flags)
241 header_output = BasicDeclare.subst(iop)
242 if regName == '':
243 decoder_output = BasicConstructor.subst(iop)
244 else:
245 decoder_output = ControlRegConstructor.subst(iop)
246 exec_output = PrivExecute.subst(iop)
247 if usesImm:
248 imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
244 opt_flags)
245 header_output = BasicDeclare.subst(iop)
246 if regName == '':
247 decoder_output = BasicConstructor.subst(iop)
248 else:
249 decoder_output = ControlRegConstructor.subst(iop)
250 exec_output = PrivExecute.subst(iop)
251 if usesImm:
252 imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
249 {"code": immCode, "check": checkCode, "reg_name": regName},
253 {"code": immCode, "check": checkCode,
254 "tlCheck": tlCheck, "reg_name": regName},
250 opt_flags)
251 header_output += BasicDeclare.subst(imm_iop)
252 if regName == '':
253 decoder_output += BasicConstructor.subst(imm_iop)
254 else:
255 decoder_output += ControlRegConstructor.subst(imm_iop)
256 exec_output += PrivExecute.subst(imm_iop)
257 decode_block = ROrImmDecode.subst(iop)
258 else:
259 decode_block = BasicDecode.subst(iop)
260 return (header_output, decoder_output, exec_output, decode_block)
261}};
262
255 opt_flags)
256 header_output += BasicDeclare.subst(imm_iop)
257 if regName == '':
258 decoder_output += BasicConstructor.subst(imm_iop)
259 else:
260 decoder_output += ControlRegConstructor.subst(imm_iop)
261 exec_output += PrivExecute.subst(imm_iop)
262 decode_block = ROrImmDecode.subst(iop)
263 else:
264 decode_block = BasicDecode.subst(iop)
265 return (header_output, decoder_output, exec_output, decode_block)
266}};
267
263def format Priv(code, *opt_flags) {{
264 checkCode = "!(Pstate<2:> || Hpstate<2:>)"
268def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{
269 checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCond
270 if checkTl != "false":
271 tlCheck = "Tl == 0"
272 else:
273 tlCheck = "false"
265 (header_output, decoder_output,
266 exec_output, decode_block) = doPrivFormat(code,
274 (header_output, decoder_output,
275 exec_output, decode_block) = doPrivFormat(code,
267 checkCode, name, Name, opt_flags)
276 checkCode, name, Name, tlCheck, opt_flags)
268}};
269
277}};
278
270def format NoPriv(code, *opt_flags) {{
279def format NoPriv(code, checkTl=false, *opt_flags) {{
271 #Instructions which use this format don't really check for
272 #any particular mode, but the disassembly is performed
273 #using the control registers actual name
274 checkCode = "false"
280 #Instructions which use this format don't really check for
281 #any particular mode, but the disassembly is performed
282 #using the control registers actual name
283 checkCode = "false"
284 if checkTl != "false":
285 tlCheck = "Tl == 0"
286 else:
287 tlCheck = "false"
275 (header_output, decoder_output,
276 exec_output, decode_block) = doPrivFormat(code,
288 (header_output, decoder_output,
289 exec_output, decode_block) = doPrivFormat(code,
277 checkCode, name, Name, opt_flags)
290 checkCode, name, Name, tlCheck, opt_flags)
278}};
279
291}};
292
280def format PrivCheck(code, extraCheckCode, *opt_flags) {{
281 checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCheckCode
282 (header_output, decoder_output,
283 exec_output, decode_block) = doPrivFormat(code,
284 checkCode, name, Name, opt_flags)
285}};
286
287def format HPriv(code, *opt_flags) {{
293def format HPriv(code, checkTl=false, *opt_flags) {{
288 checkCode = "!Hpstate<2:2>"
294 checkCode = "!Hpstate<2:2>"
295 if checkTl != "false":
296 tlCheck = "Tl == 0"
297 else:
298 tlCheck = "false"
289 (header_output, decoder_output,
290 exec_output, decode_block) = doPrivFormat(code,
299 (header_output, decoder_output,
300 exec_output, decode_block) = doPrivFormat(code,
291 checkCode, name, Name, opt_flags)
301 checkCode, name, Name, tlCheck, opt_flags)
292}};
293
302}};
303