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