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
| 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.
| 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:
| 55 class RdPriv : public Priv 56 { 57 protected:
|
58 //Constructor
| 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
| 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.
| 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:
| 73 class WrPriv : public Priv 74 { 75 protected:
|
76 //Constructor
| 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
| 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.
| 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:
| 107 class WrPrivImm : public PrivImm 108 { 109 protected:
|
110 //Constructor
| 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 {{
| 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
| 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
| 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
| 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
| 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
| 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, " ");
| 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 {
| 156 // If the first reg is %g0, don't print it. 157 // This improves readability 158 if (_srcRegIdx[0] != 0) {
|
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, " ");
| 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, " ");
|
177 //If the first reg is %g0, don't print it. 178 //This improves readability 179 if(_srcRegIdx[0] != 0) 180 {
| 176 // If the first reg is %g0, don't print it. 177 // This improves readability 178 if (_srcRegIdx[0] != 0) {
|
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
| 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 {{ 189 inline %(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 } 195}}; 196 197def template PrivExecute {{ 198 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 199 Trace::InstRecord *traceData) const 200 { 201 %(op_decl)s; 202 %(op_rd)s; 203
|
206 //If the processor isn't in privileged mode, fault out right away 207 if(%(check)s)
| 204 // If the processor isn't in privileged mode, fault out right away 205 if (%(check)s)
|
208 return new PrivilegedAction; 209
| 206 return new PrivilegedAction; 207
|
210 if(%(tlCheck)s)
| 208 if (%(tlCheck)s)
|
211 return new IllegalInstruction; 212 213 Fault fault = NoFault; 214 %(code)s; 215 %(op_wb)s; 216 return fault; 217 } 218}}; 219 220let {{ 221 def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags): 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, 242 {"code": code, "check": checkCode, 243 "tlCheck": tlCheck, "reg_name": regName}, 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', 253 {"code": immCode, "check": checkCode, 254 "tlCheck": tlCheck, "reg_name": regName}, 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 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" 274 (header_output, decoder_output, 275 exec_output, decode_block) = doPrivFormat(code, 276 checkCode, name, Name, tlCheck, opt_flags) 277}}; 278 279def format NoPriv(code, checkTl=false, *opt_flags) {{ 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" 288 (header_output, decoder_output, 289 exec_output, decode_block) = doPrivFormat(code, 290 checkCode, name, Name, tlCheck, opt_flags) 291}}; 292 293def format HPriv(code, checkTl=false, *opt_flags) {{ 294 checkCode = "!Hpstate<2:2>" 295 if checkTl != "false": 296 tlCheck = "Tl == 0" 297 else: 298 tlCheck = "false" 299 (header_output, decoder_output, 300 exec_output, decode_block) = doPrivFormat(code, 301 checkCode, name, Name, tlCheck, opt_flags) 302}}; 303
| 209 return new IllegalInstruction; 210 211 Fault fault = NoFault; 212 %(code)s; 213 %(op_wb)s; 214 return fault; 215 } 216}}; 217 218let {{ 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 = '' 227 for mnem in ["rdhpr", "rdpr", "rd"]: 228 if name.startswith(mnem): 229 regName = name[len(mnem):] 230 name = mnem 231 regBase = 'RdPriv' 232 break 233 for mnem in ["wrhpr", "wrpr", "wr"]: 234 if name.startswith(mnem): 235 regName = name[len(mnem):] 236 name = mnem 237 regBase = 'WrPriv' 238 break 239 iop = InstObjParams(name, Name, regBase, 240 {"code": code, "check": checkCode, 241 "tlCheck": tlCheck, "reg_name": regName}, 242 opt_flags) 243 header_output = BasicDeclare.subst(iop) 244 if regName == '': 245 decoder_output = BasicConstructor.subst(iop) 246 else: 247 decoder_output = ControlRegConstructor.subst(iop) 248 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}, 253 opt_flags) 254 header_output += BasicDeclare.subst(imm_iop) 255 if regName == '': 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 266def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{ 267 checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % 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) 275}}; 276 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) 289}}; 290 291def format HPriv(code, checkTl=false, *opt_flags) {{ 292 checkCode = "!Hpstate<2:2>" 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) 300}}; 301
|