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 |