priv.isa revision 3599
1// Copyright (c) 2006 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 printSrcReg(response, 0); 157 ccprintf(response, ", "); 158 printSrcReg(response, 1); 159 ccprintf(response, ", %%%s", regName); 160 161 return response.str(); 162 } 163 164 std::string WrPrivImm::generateDisassembly(Addr pc, 165 const SymbolTable *symtab) const 166 { 167 std::stringstream response; 168 169 printMnemonic(response, mnemonic); 170 171 ccprintf(response, " "); 172 printSrcReg(response, 0); 173 ccprintf(response, ", 0x%x, %%%s", imm, regName); 174 175 return response.str(); 176 } 177}}; 178 179def 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") 183 { 184 %(constructor)s; 185 } 186}}; 187 188def template PrivExecute {{ 189 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 190 Trace::InstRecord *traceData) const 191 { 192 %(op_decl)s; 193 %(op_rd)s; 194 195 //If the processor isn't in privileged mode, fault out right away 196 if(%(check)s) 197 return new PrivilegedAction; 198 199 Fault fault = NoFault; 200 %(code)s; 201 %(op_wb)s; 202 return fault; 203 } 204}}; 205 206let {{ 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 212 #base class. 213 regBase = 'Priv' 214 regName = '' 215 for mnem in ["rdhpr", "rdpr", "rd"]: 216 if name.startswith(mnem): 217 regName = name[len(mnem):] 218 name = mnem 219 regBase = 'RdPriv' 220 break 221 for mnem in ["wrhpr", "wrpr", "wr"]: 222 if name.startswith(mnem): 223 regName = name[len(mnem):] 224 name = mnem 225 regBase = 'WrPriv' 226 break 227 iop = InstObjParams(name, Name, regBase, code, 228 opt_flags, {"check": checkCode, "reg_name": regName}) 229 header_output = BasicDeclare.subst(iop) 230 if regName == '': 231 decoder_output = BasicConstructor.subst(iop) 232 else: 233 decoder_output = ControlRegConstructor.subst(iop) 234 exec_output = PrivExecute.subst(iop) 235 if usesImm: 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) 239 if regName == '': 240 decoder_output += BasicConstructor.subst(imm_iop) 241 else: 242 decoder_output += ControlRegConstructor.subst(imm_iop) 243 exec_output += PrivExecute.subst(imm_iop) 244 decode_block = ROrImmDecode.subst(iop) 245 else: 246 decode_block = BasicDecode.subst(iop) 247 return (header_output, decoder_output, exec_output, decode_block) 248}}; 249 250def 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) 255}}; 256 257def 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 261 checkCode = "false" 262 (header_output, decoder_output, 263 exec_output, decode_block) = doPrivFormat(code, 264 checkCode, name, Name, opt_flags) 265}}; 266 267def 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) 272}}; 273 274def 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) 279}}; 280 281