ldstop.isa revision 4867:2de05bc73640
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 Twin64_t alignedMem; 127 fault = read(xc, EA, alignedMem, 0); 128 int offset = EA & (dataSize - 1); 129 if(dataSize != 8 || !offset) 130 { 131 Mem = bits(alignedMem.a, 132 (offset + dataSize) * 8 - 1, offset * 8); 133 } 134 else 135 { 136 Mem = alignedMem.b << (dataSize - offset) * 8; 137 Mem |= bits(alignedMem.a, dataSize * 8 - 1, offset * 8); 138 } 139 140 if(fault == NoFault) 141 { 142 %(code)s; 143 } 144 if(fault == NoFault) 145 { 146 %(op_wb)s; 147 } 148 149 return fault; 150 } 151}}; 152 153def template MicroLoadInitiateAcc {{ 154 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 155 Trace::InstRecord * traceData) const 156 { 157 Fault fault = NoFault; 158 Addr EA; 159 160 %(op_decl)s; 161 %(op_rd)s; 162 %(ea_code)s; 163 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 164 165 int offset = EA & (dataSize - 1); 166 Twin64_t alignedMem; 167 fault = read(xc, EA, alignedMem, offset); 168 169 return fault; 170 } 171}}; 172 173def template MicroLoadCompleteAcc {{ 174 Fault %(class_name)s::completeAcc(PacketPtr pkt, 175 %(CPU_exec_context)s * xc, 176 Trace::InstRecord * traceData) const 177 { 178 Fault fault = NoFault; 179 180 %(op_decl)s; 181 %(op_rd)s; 182 183 Twin64_t alignedMem = pkt->get<Twin64_t>(); 184 int offset = pkt->req->getFlags(); 185 if(dataSize != 8 || !offset) 186 { 187 Mem = bits(alignedMem.a, 188 (offset + dataSize) * 8 - 1, offset * 8); 189 } 190 else 191 { 192 Mem = alignedMem.b << (dataSize - offset) * 8; 193 Mem |= bits(alignedMem.a, dataSize * 8 - 1, offset * 8); 194 } 195 %(code)s; 196 197 if(fault == NoFault) 198 { 199 %(op_wb)s; 200 } 201 202 return fault; 203 } 204}}; 205 206// Store templates 207 208def template MicroStoreExecute {{ 209 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 210 Trace::InstRecord *traceData) const 211 { 212 Fault fault = NoFault; 213 214 Addr EA; 215 %(op_decl)s; 216 %(op_rd)s; 217 %(ea_code)s; 218 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 219 220 %(code)s; 221 222 if(fault == NoFault) 223 { 224 int offset = EA & (dataSize - 1); 225 226 Twin64_t alignedMem; 227 alignedMem.a = Mem << (offset * 8); 228 alignedMem.b = 229 bits(Mem, dataSize * 8 - 1, (dataSize - offset) * 8); 230 231 fault = write(xc, alignedMem, EA, 0); 232 if(fault == NoFault) 233 { 234 %(op_wb)s; 235 } 236 } 237 238 return fault; 239 } 240}}; 241 242def template MicroStoreInitiateAcc {{ 243 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 244 Trace::InstRecord * traceData) const 245 { 246 Fault fault = NoFault; 247 248 Addr EA; 249 %(op_decl)s; 250 %(op_rd)s; 251 %(ea_code)s; 252 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 253 254 %(code)s; 255 256 if(fault == NoFault) 257 { 258 int offset = EA & (dataSize - 1); 259 260 Twin64_t alignedMem; 261 alignedMem.a = Mem << (offset * 8); 262 alignedMem.b = 263 bits(Mem, dataSize * 8 - 1, (dataSize - offset) * 8); 264 265 fault = write(xc, alignedMem, EA, 0); 266 if(fault == NoFault) 267 { 268 %(op_wb)s; 269 } 270 } 271 return fault; 272 } 273}}; 274 275def template MicroStoreCompleteAcc {{ 276 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 277 Trace::InstRecord * traceData) const 278 { 279 return NoFault; 280 } 281}}; 282 283// Common templates 284 285//This delcares the initiateAcc function in memory operations 286def template InitiateAccDeclare {{ 287 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 288}}; 289 290//This declares the completeAcc function in memory operations 291def template CompleteAccDeclare {{ 292 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 293}}; 294 295def template MicroLdStOpDeclare {{ 296 class %(class_name)s : public %(base_class)s 297 { 298 protected: 299 void buildMe(); 300 301 public: 302 %(class_name)s(ExtMachInst _machInst, 303 const char * instMnem, 304 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 305 uint8_t _scale, RegIndex _index, RegIndex _base, 306 uint64_t _disp, uint8_t _segment, 307 RegIndex _data, 308 uint8_t _dataSize, uint8_t _addressSize); 309 310 %(class_name)s(ExtMachInst _machInst, 311 const char * instMnem, 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 317 %(BasicExecDeclare)s 318 319 %(InitiateAccDeclare)s 320 321 %(CompleteAccDeclare)s 322 }; 323}}; 324 325def template MicroLdStOpConstructor {{ 326 327 inline void %(class_name)s::buildMe() 328 { 329 %(constructor)s; 330 } 331 332 inline %(class_name)s::%(class_name)s( 333 ExtMachInst machInst, const char * instMnem, 334 uint8_t _scale, RegIndex _index, RegIndex _base, 335 uint64_t _disp, uint8_t _segment, 336 RegIndex _data, 337 uint8_t _dataSize, uint8_t _addressSize) : 338 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 339 false, false, false, false, 340 _scale, _index, _base, 341 _disp, _segment, _data, 342 _dataSize, _addressSize, %(op_class)s) 343 { 344 buildMe(); 345 } 346 347 inline %(class_name)s::%(class_name)s( 348 ExtMachInst machInst, const char * instMnem, 349 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 350 uint8_t _scale, RegIndex _index, RegIndex _base, 351 uint64_t _disp, uint8_t _segment, 352 RegIndex _data, 353 uint8_t _dataSize, uint8_t _addressSize) : 354 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 355 isMicro, isDelayed, isFirst, isLast, 356 _scale, _index, _base, 357 _disp, _segment, _data, 358 _dataSize, _addressSize, %(op_class)s) 359 { 360 buildMe(); 361 } 362}}; 363 364let {{ 365 class LdStOp(X86Microop): 366 def __init__(self, data, segment, addr, disp, dataSize): 367 self.data = data 368 [self.scale, self.index, self.base] = addr 369 self.disp = disp 370 self.segment = segment 371 self.dataSize = dataSize 372 self.addressSize = "env.addressSize" 373 374 def getAllocator(self, *microFlags): 375 allocator = '''new %(class_name)s(machInst, mnemonic 376 %(flags)s, %(scale)s, %(index)s, %(base)s, 377 %(disp)s, %(segment)s, %(data)s, 378 %(dataSize)s, %(addressSize)s)''' % { 379 "class_name" : self.className, 380 "flags" : self.microFlagsText(microFlags), 381 "scale" : self.scale, "index" : self.index, 382 "base" : self.base, 383 "disp" : self.disp, 384 "segment" : self.segment, "data" : self.data, 385 "dataSize" : self.dataSize, "addressSize" : self.addressSize} 386 return allocator 387}}; 388 389let {{ 390 391 # Make these empty strings so that concatenating onto 392 # them will always work. 393 header_output = "" 394 decoder_output = "" 395 exec_output = "" 396 397 calculateEA = "EA = SegBase + scale * Index + Base + disp;" 398 399 def defineMicroLoadOp(mnemonic, code): 400 global header_output 401 global decoder_output 402 global exec_output 403 global microopClasses 404 Name = mnemonic 405 name = mnemonic.lower() 406 407 # Build up the all register version of this micro op 408 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 409 {"code": code, "ea_code": calculateEA}) 410 header_output += MicroLdStOpDeclare.subst(iop) 411 decoder_output += MicroLdStOpConstructor.subst(iop) 412 exec_output += MicroLoadExecute.subst(iop) 413 exec_output += MicroLoadInitiateAcc.subst(iop) 414 exec_output += MicroLoadCompleteAcc.subst(iop) 415 416 class LoadOp(LdStOp): 417 def __init__(self, data, segment, addr, 418 disp = 0, dataSize="env.dataSize"): 419 super(LoadOp, self).__init__(data, segment, 420 addr, disp, dataSize) 421 self.className = Name 422 self.mnemonic = name 423 424 microopClasses[name] = LoadOp 425 426 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 427 428 def defineMicroStoreOp(mnemonic, code): 429 global header_output 430 global decoder_output 431 global exec_output 432 global microopClasses 433 Name = mnemonic 434 name = mnemonic.lower() 435 436 # Build up the all register version of this micro op 437 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 438 {"code": code, "ea_code": calculateEA}) 439 header_output += MicroLdStOpDeclare.subst(iop) 440 decoder_output += MicroLdStOpConstructor.subst(iop) 441 exec_output += MicroStoreExecute.subst(iop) 442 exec_output += MicroStoreInitiateAcc.subst(iop) 443 exec_output += MicroStoreCompleteAcc.subst(iop) 444 445 class StoreOp(LdStOp): 446 def __init__(self, data, segment, addr, 447 disp = 0, dataSize="env.dataSize"): 448 super(StoreOp, self).__init__(data, segment, 449 addr, disp, dataSize) 450 self.className = Name 451 self.mnemonic = name 452 453 microopClasses[name] = StoreOp 454 455 defineMicroStoreOp('St', 'Mem = Data;') 456 457 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 458 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA}) 459 header_output += MicroLeaDeclare.subst(iop) 460 decoder_output += MicroLdStOpConstructor.subst(iop) 461 exec_output += MicroLeaExecute.subst(iop) 462 463 class LeaOp(LdStOp): 464 def __init__(self, data, segment, addr, 465 disp = 0, dataSize="env.dataSize"): 466 super(LeaOp, self).__init__(data, segment, 467 addr, disp, dataSize) 468 self.className = "Lea" 469 self.mnemonic = "lea" 470 471 microopClasses["lea"] = LeaOp 472}}; 473 474