ldstop.isa revision 4712
1// Copyright (c) 2007 The Hewlett-Packard Development Company 2// All rights reserved. 3// 4// Redistribution and use of this software in source and binary forms, 5// with or without modification, are permitted provided that the 6// following conditions are met: 7// 8// The software must be used only for Non-Commercial Use which means any 9// use which is NOT directed to receiving any direct monetary 10// compensation for, or commercial advantage from such use. Illustrative 11// examples of non-commercial use are academic research, personal study, 12// teaching, education and corporate research & development. 13// Illustrative examples of commercial use are distributing products for 14// commercial advantage and providing services using the software for 15// commercial advantage. 16// 17// If you wish to use this software or functionality therein that may be 18// covered by patents for commercial use, please contact: 19// Director of Intellectual Property Licensing 20// Office of Strategy and Technology 21// Hewlett-Packard Company 22// 1501 Page Mill Road 23// Palo Alto, California 94304 24// 25// Redistributions of source code must retain the above copyright notice, 26// this list of conditions and the following disclaimer. Redistributions 27// in binary form must reproduce the above copyright notice, this list of 28// conditions and the following disclaimer in the documentation and/or 29// other materials provided with the distribution. Neither the name of 30// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 31// contributors may be used to endorse or promote products derived from 32// this software without specific prior written permission. No right of 33// sublicense is granted herewith. Derivatives of the software and 34// output created using the software may be prepared, but only for 35// Non-Commercial Uses. Derivatives of the software may be shared with 36// others provided: (i) the others agree to abide by the list of 37// conditions herein which includes the Non-Commercial Use restrictions; 38// and (ii) such Derivatives of the software include the above copyright 39// notice to acknowledge the contribution from this software where 40// applicable, this list of conditions and the disclaimer below. 41// 42// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53// 54// Authors: Gabe Black 55 56////////////////////////////////////////////////////////////////////////// 57// 58// LdStOp Microop templates 59// 60////////////////////////////////////////////////////////////////////////// 61 62// LEA template 63 64def template MicroLeaExecute {{ 65 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 66 Trace::InstRecord *traceData) const 67 { 68 Fault fault = NoFault; 69 Addr EA; 70 71 %(op_decl)s; 72 %(op_rd)s; 73 %(ea_code)s; 74 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 75 76 %(code)s; 77 if(fault == NoFault) 78 { 79 %(op_wb)s; 80 } 81 82 return fault; 83 } 84}}; 85 86def template MicroLeaDeclare {{ 87 class %(class_name)s : public %(base_class)s 88 { 89 protected: 90 void buildMe(); 91 92 public: 93 %(class_name)s(ExtMachInst _machInst, 94 const char * instMnem, 95 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 96 uint8_t _scale, RegIndex _index, RegIndex _base, 97 uint64_t _disp, uint8_t _segment, 98 RegIndex _data, 99 uint8_t _dataSize, uint8_t _addressSize); 100 101 %(class_name)s(ExtMachInst _machInst, 102 const char * instMnem, 103 uint8_t _scale, RegIndex _index, RegIndex _base, 104 uint64_t _disp, uint8_t _segment, 105 RegIndex _data, 106 uint8_t _dataSize, uint8_t _addressSize); 107 108 %(BasicExecDeclare)s 109 }; 110}}; 111 112// Load templates 113 114def template MicroLoadExecute {{ 115 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 116 Trace::InstRecord *traceData) const 117 { 118 Fault fault = NoFault; 119 Addr EA; 120 121 %(op_decl)s; 122 %(op_rd)s; 123 %(ea_code)s; 124 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 125 126 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); 127 if(fault == NoFault) 128 { 129 %(code)s; 130 } 131 if(fault == NoFault) 132 { 133 %(op_wb)s; 134 } 135 136 return fault; 137 } 138}}; 139 140def template MicroLoadInitiateAcc {{ 141 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 142 Trace::InstRecord * traceData) const 143 { 144 Fault fault = NoFault; 145 Addr EA; 146 147 %(op_decl)s; 148 %(op_rd)s; 149 %(ea_code)s; 150 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 151 152 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); 153 154 return fault; 155 } 156}}; 157 158def template MicroLoadCompleteAcc {{ 159 Fault %(class_name)s::completeAcc(PacketPtr pkt, 160 %(CPU_exec_context)s * xc, 161 Trace::InstRecord * traceData) const 162 { 163 Fault fault = NoFault; 164 165 %(op_decl)s; 166 %(op_rd)s; 167 168 Mem = pkt->get<typeof(Mem)>(); 169 %(code)s; 170 171 if(fault == NoFault) 172 { 173 %(op_wb)s; 174 } 175 176 return fault; 177 } 178}}; 179 180// Store templates 181 182def template MicroStoreExecute {{ 183 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 184 Trace::InstRecord *traceData) const 185 { 186 Fault fault = NoFault; 187 188 Addr EA; 189 %(op_decl)s; 190 %(op_rd)s; 191 %(ea_code)s; 192 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 193 194 %(code)s; 195 196 if(fault == NoFault) 197 { 198 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, 199 EA, 0, 0); 200 } 201 if(fault == NoFault) 202 { 203 %(op_wb)s; 204 } 205 206 return fault; 207 } 208}}; 209 210def template MicroStoreInitiateAcc {{ 211 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 212 Trace::InstRecord * traceData) const 213 { 214 Fault fault = NoFault; 215 216 Addr EA; 217 %(op_decl)s; 218 %(op_rd)s; 219 %(ea_code)s; 220 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 221 222 %(code)s; 223 224 if(fault == NoFault) 225 { 226 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, 227 EA, 0, 0); 228 } 229 if(fault == NoFault) 230 { 231 %(op_wb)s; 232 } 233 return fault; 234 } 235}}; 236 237def template MicroStoreCompleteAcc {{ 238 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 239 Trace::InstRecord * traceData) const 240 { 241 return NoFault; 242 } 243}}; 244 245// Common templates 246 247//This delcares the initiateAcc function in memory operations 248def template InitiateAccDeclare {{ 249 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 250}}; 251 252//This declares the completeAcc function in memory operations 253def template CompleteAccDeclare {{ 254 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 255}}; 256 257def template MicroLdStOpDeclare {{ 258 class %(class_name)s : public %(base_class)s 259 { 260 protected: 261 void buildMe(); 262 263 public: 264 %(class_name)s(ExtMachInst _machInst, 265 const char * instMnem, 266 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 267 uint8_t _scale, RegIndex _index, RegIndex _base, 268 uint64_t _disp, uint8_t _segment, 269 RegIndex _data, 270 uint8_t _dataSize, uint8_t _addressSize); 271 272 %(class_name)s(ExtMachInst _machInst, 273 const char * instMnem, 274 uint8_t _scale, RegIndex _index, RegIndex _base, 275 uint64_t _disp, uint8_t _segment, 276 RegIndex _data, 277 uint8_t _dataSize, uint8_t _addressSize); 278 279 %(BasicExecDeclare)s 280 281 %(InitiateAccDeclare)s 282 283 %(CompleteAccDeclare)s 284 }; 285}}; 286 287def template MicroLdStOpConstructor {{ 288 289 inline void %(class_name)s::buildMe() 290 { 291 %(constructor)s; 292 } 293 294 inline %(class_name)s::%(class_name)s( 295 ExtMachInst machInst, const char * instMnem, 296 uint8_t _scale, RegIndex _index, RegIndex _base, 297 uint64_t _disp, uint8_t _segment, 298 RegIndex _data, 299 uint8_t _dataSize, uint8_t _addressSize) : 300 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 301 false, false, false, false, 302 _scale, _index, _base, 303 _disp, _segment, _data, 304 _dataSize, _addressSize, %(op_class)s) 305 { 306 buildMe(); 307 } 308 309 inline %(class_name)s::%(class_name)s( 310 ExtMachInst machInst, const char * instMnem, 311 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 312 uint8_t _scale, RegIndex _index, RegIndex _base, 313 uint64_t _disp, uint8_t _segment, 314 RegIndex _data, 315 uint8_t _dataSize, uint8_t _addressSize) : 316 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 317 isMicro, isDelayed, isFirst, isLast, 318 _scale, _index, _base, 319 _disp, _segment, _data, 320 _dataSize, _addressSize, %(op_class)s) 321 { 322 buildMe(); 323 } 324}}; 325 326let {{ 327 class LdStOp(X86Microop): 328 def __init__(self, data, segment, addr, disp, dataSize): 329 self.data = data 330 [self.scale, self.index, self.base] = addr 331 self.disp = disp 332 self.segment = segment 333 self.dataSize = dataSize 334 self.addressSize = "env.addressSize" 335 336 def getAllocator(self, *microFlags): 337 allocator = '''new %(class_name)s(machInst, mnemonic 338 %(flags)s, %(scale)s, %(index)s, %(base)s, 339 %(disp)s, %(segment)s, %(data)s, 340 %(dataSize)s, %(addressSize)s)''' % { 341 "class_name" : self.className, 342 "flags" : self.microFlagsText(microFlags), 343 "scale" : self.scale, "index" : self.index, 344 "base" : self.base, 345 "disp" : self.disp, 346 "segment" : self.segment, "data" : self.data, 347 "dataSize" : self.dataSize, "addressSize" : self.addressSize} 348 return allocator 349}}; 350 351let {{ 352 353 # Make these empty strings so that concatenating onto 354 # them will always work. 355 header_output = "" 356 decoder_output = "" 357 exec_output = "" 358 359 calculateEA = "EA = scale * Index + Base + disp;" 360 361 def defineMicroLoadOp(mnemonic, code): 362 global header_output 363 global decoder_output 364 global exec_output 365 global microopClasses 366 Name = mnemonic 367 name = mnemonic.lower() 368 369 # Build up the all register version of this micro op 370 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 371 {"code": code, "ea_code": calculateEA}) 372 header_output += MicroLdStOpDeclare.subst(iop) 373 decoder_output += MicroLdStOpConstructor.subst(iop) 374 exec_output += MicroLoadExecute.subst(iop) 375 exec_output += MicroLoadInitiateAcc.subst(iop) 376 exec_output += MicroLoadCompleteAcc.subst(iop) 377 378 class LoadOp(LdStOp): 379 def __init__(self, data, segment, addr, 380 disp = 0, dataSize="env.dataSize"): 381 super(LoadOp, self).__init__(data, segment, 382 addr, disp, dataSize) 383 self.className = Name 384 self.mnemonic = name 385 386 microopClasses[name] = LoadOp 387 388 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 389 390 def defineMicroStoreOp(mnemonic, code): 391 global header_output 392 global decoder_output 393 global exec_output 394 global microopClasses 395 Name = mnemonic 396 name = mnemonic.lower() 397 398 # Build up the all register version of this micro op 399 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 400 {"code": code, "ea_code": calculateEA}) 401 header_output += MicroLdStOpDeclare.subst(iop) 402 decoder_output += MicroLdStOpConstructor.subst(iop) 403 exec_output += MicroStoreExecute.subst(iop) 404 exec_output += MicroStoreInitiateAcc.subst(iop) 405 exec_output += MicroStoreCompleteAcc.subst(iop) 406 407 class StoreOp(LdStOp): 408 def __init__(self, data, segment, addr, 409 disp = 0, dataSize="env.dataSize"): 410 super(StoreOp, self).__init__(data, segment, 411 addr, disp, dataSize) 412 self.className = Name 413 self.mnemonic = name 414 415 microopClasses[name] = StoreOp 416 417 defineMicroStoreOp('St', 'Mem = Data;') 418 419 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 420 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA}) 421 header_output += MicroLeaDeclare.subst(iop) 422 decoder_output += MicroLdStOpConstructor.subst(iop) 423 exec_output += MicroLeaExecute.subst(iop) 424 425 class LeaOp(LdStOp): 426 def __init__(self, data, segment, addr, 427 disp = 0, dataSize="env.dataSize"): 428 super(LeaOp, self).__init__(data, segment, 429 addr, disp, dataSize) 430 self.className = "Lea" 431 self.mnemonic = "lea" 432 433 microopClasses["lea"] = LeaOp 434}}; 435 436