priv.isa (12234:78ece221f9f5) priv.isa (12287:4163eeb6210c)
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

--- 19 unchanged lines hidden (view full) ---

28// Gabe Black
29// Steve Reinhardt
30
31////////////////////////////////////////////////////////////////////
32//
33// Privilege mode instructions
34//
35
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

--- 19 unchanged lines hidden (view full) ---

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
126 Priv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
127 {
128 std::stringstream response;
129
130 printMnemonic(response, mnemonic);
131
132 return response.str();
133 }
134
135 std::string
136 RdPriv::generateDisassembly(Addr pc, 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
149 WrPriv::generateDisassembly(Addr pc, 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].index() != 0) {
159 printSrcReg(response, 0);
160 ccprintf(response, ", ");
161 }
162 printSrcReg(response, 1);
163 ccprintf(response, ", %%%s", regName);
164
165 return response.str();
166 }
167
168 std::string WrPrivImm::generateDisassembly(Addr pc,
169 const SymbolTable *symtab) const
170 {
171 std::stringstream response;
172
173 printMnemonic(response, mnemonic);
174
175 ccprintf(response, " ");
176 // If the first reg is %g0, don't print it.
177 // This improves readability
178 if (_srcRegIdx[0].index() != 0) {
179 printSrcReg(response, 0);
180 ccprintf(response, ", ");
181 }
182 ccprintf(response, "0x%x, %%%s", imm, regName);
183
184 return response.str();
185 }
186}};
187
188def template ControlRegConstructor {{
36def template ControlRegConstructor {{
189 %(class_name)s::%(class_name)s(ExtMachInst machInst)
190 : %(base_class)s("%(mnemonic)s", machInst,
191 %(op_class)s, "%(reg_name)s")
192 {
193 %(constructor)s;
194 }
37%(class_name)s::%(class_name)s(ExtMachInst machInst) :
38 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, "%(reg_name)s")
39{
40 %(constructor)s;
41}
195}};
196
197def template PrivExecute {{
42}};
43
44def template PrivExecute {{
198 Fault %(class_name)s::execute(ExecContext *xc,
199 Trace::InstRecord *traceData) const
200 {
201 %(op_decl)s;
202 %(op_rd)s;
45Fault
46%(class_name)s::execute(ExecContext *xc, Trace::InstRecord *traceData) const
47{
48 %(op_decl)s;
49 %(op_rd)s;
203
50
204 // If the processor isn't in privileged mode, fault out right away
205 if (%(check)s)
206 return std::make_shared<PrivilegedAction>();
51 // If the processor isn't in privileged mode, fault out right away
52 if (%(check)s)
53 return std::make_shared();
207
54
208 if (%(tlCheck)s)
209 return std::make_shared<IllegalInstruction>();
55 %(tl_check)s
210
56
211 Fault fault = NoFault;
212 %(code)s;
213 %(op_wb)s;
214 return fault;
215 }
57 Fault fault = NoFault;
58 %(code)s;
59 %(op_wb)s;
60 return fault;
61}
216}};
217
218let {{
62}};
63
64let {{
219 def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags):
220 (usesImm, code, immCode,
221 rString, iString) = splitOutImm(code)
222 #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
223 #cut any other info out of the mnemonic. Also pick a different
224 #base class.
225 regBase = 'Priv'
226 regName = ''
65 tl_check_code = '''
66 if (Tl == 0)
67 return std::make_shared<IllegalInstruction>();
68'''
69
70 def doPrivFormat(code, check_code, name, Name, opt_flags, check_tl=False):
71 (uses_imm, code, imm_code, r_string, i_string) = splitOutImm(code)
72 tl_check = tl_check_code if check_tl else ''
73 # If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
74 # cut any other info out of the mnemonic. Also pick a different
75 # base class.
76 reg_base = 'Priv'
77 reg_name = ''
227 for mnem in ["rdhpr", "rdpr", "rd"]:
228 if name.startswith(mnem):
78 for mnem in ["rdhpr", "rdpr", "rd"]:
79 if name.startswith(mnem):
229 regName = name[len(mnem):]
80 reg_name = name[len(mnem):]
230 name = mnem
81 name = mnem
231 regBase = 'RdPriv'
82 reg_base = 'RdPriv'
232 break
233 for mnem in ["wrhpr", "wrpr", "wr"]:
234 if name.startswith(mnem):
83 break
84 for mnem in ["wrhpr", "wrpr", "wr"]:
85 if name.startswith(mnem):
235 regName = name[len(mnem):]
86 reg_name = name[len(mnem):]
236 name = mnem
87 name = mnem
237 regBase = 'WrPriv'
88 reg_base = 'WrPriv'
238 break
89 break
239 iop = InstObjParams(name, Name, regBase,
240 {"code": code, "check": checkCode,
241 "tlCheck": tlCheck, "reg_name": regName},
90 iop = InstObjParams(name, Name, reg_base,
91 {"code": code, "check": check_code,
92 "tl_check": tl_check, "reg_name": reg_name},
242 opt_flags)
243 header_output = BasicDeclare.subst(iop)
93 opt_flags)
94 header_output = BasicDeclare.subst(iop)
244 if regName == '':
95 if reg_name == '':
245 decoder_output = BasicConstructor.subst(iop)
246 else:
247 decoder_output = ControlRegConstructor.subst(iop)
248 exec_output = PrivExecute.subst(iop)
96 decoder_output = BasicConstructor.subst(iop)
97 else:
98 decoder_output = ControlRegConstructor.subst(iop)
99 exec_output = PrivExecute.subst(iop)
249 if usesImm:
250 imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
251 {"code": immCode, "check": checkCode,
252 "tlCheck": tlCheck, "reg_name": regName},
100 if uses_imm:
101 imm_iop = InstObjParams(name, Name + 'Imm', reg_base + 'Imm',
102 {"code": imm_code, "check": check_code,
103 "tl_check": tl_check, "reg_name": reg_name},
253 opt_flags)
254 header_output += BasicDeclare.subst(imm_iop)
104 opt_flags)
105 header_output += BasicDeclare.subst(imm_iop)
255 if regName == '':
106 if reg_name == '':
256 decoder_output += BasicConstructor.subst(imm_iop)
257 else:
258 decoder_output += ControlRegConstructor.subst(imm_iop)
259 exec_output += PrivExecute.subst(imm_iop)
260 decode_block = ROrImmDecode.subst(iop)
261 else:
262 decode_block = BasicDecode.subst(iop)
263 return (header_output, decoder_output, exec_output, decode_block)
264}};
265
107 decoder_output += BasicConstructor.subst(imm_iop)
108 else:
109 decoder_output += ControlRegConstructor.subst(imm_iop)
110 exec_output += PrivExecute.subst(imm_iop)
111 decode_block = ROrImmDecode.subst(iop)
112 else:
113 decode_block = BasicDecode.subst(iop)
114 return (header_output, decoder_output, exec_output, decode_block)
115}};
116
266def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{
267 checkCode = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
268 if checkTl != "false":
269 tlCheck = "Tl == 0"
270 else:
271 tlCheck = "false"
272 (header_output, decoder_output,
273 exec_output, decode_block) = doPrivFormat(code,
274 checkCode, name, Name, tlCheck, opt_flags)
117def format Priv(code, extraCond=true, check_tl=false, *opt_flags) {{
118 check_code = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
119 (header_output, decoder_output, exec_output, decode_block) = \
120 doPrivFormat(code, check_code, name, Name, opt_flags,
121 check_tl=(check_tl != 'false'))
275}};
276
122}};
123
277def format NoPriv(code, checkTl=false, *opt_flags) {{
278 #Instructions which use this format don't really check for
279 #any particular mode, but the disassembly is performed
280 #using the control registers actual name
281 checkCode = "false"
282 if checkTl != "false":
283 tlCheck = "Tl == 0"
284 else:
285 tlCheck = "false"
286 (header_output, decoder_output,
287 exec_output, decode_block) = doPrivFormat(code,
288 checkCode, name, Name, tlCheck, opt_flags)
124def format NoPriv(code, *opt_flags) {{
125 # Instructions which use this format don't really check for any
126 # particular mode, but the disassembly is performed using the control
127 # register's actual name
128 check_code = "false"
129 (header_output, decoder_output, exec_output, decode_block) = \
130 doPrivFormat(code, check_code, name, Name, opt_flags)
289}};
290
131}};
132
291def format HPriv(code, checkTl=false, *opt_flags) {{
292 checkCode = "!Hpstate.hpriv"
293 if checkTl != "false":
294 tlCheck = "Tl == 0"
295 else:
296 tlCheck = "false"
297 (header_output, decoder_output,
298 exec_output, decode_block) = doPrivFormat(code,
299 checkCode, name, Name, tlCheck, opt_flags)
133def format HPriv(code, check_tl=false, *opt_flags) {{
134 check_code = "!Hpstate.hpriv"
135 (header_output, decoder_output, exec_output, decode_block) = \
136 doPrivFormat(code, check_code, name, Name, opt_flags,
137 check_tl=(check_tl != 'false'))
300}};
301
138}};
139