ldstop.isa revision 5232:d3801ea2792e
112855Sgabeblack@google.com// Copyright (c) 2007 The Hewlett-Packard Development Company 212855Sgabeblack@google.com// All rights reserved. 312855Sgabeblack@google.com// 412855Sgabeblack@google.com// Redistribution and use of this software in source and binary forms, 512855Sgabeblack@google.com// with or without modification, are permitted provided that the 612855Sgabeblack@google.com// following conditions are met: 712855Sgabeblack@google.com// 812855Sgabeblack@google.com// The software must be used only for Non-Commercial Use which means any 912855Sgabeblack@google.com// use which is NOT directed to receiving any direct monetary 1012855Sgabeblack@google.com// compensation for, or commercial advantage from such use. Illustrative 1112855Sgabeblack@google.com// examples of non-commercial use are academic research, personal study, 1212855Sgabeblack@google.com// teaching, education and corporate research & development. 1312855Sgabeblack@google.com// Illustrative examples of commercial use are distributing products for 1412855Sgabeblack@google.com// commercial advantage and providing services using the software for 1512855Sgabeblack@google.com// commercial advantage. 1612855Sgabeblack@google.com// 1712855Sgabeblack@google.com// If you wish to use this software or functionality therein that may be 1812855Sgabeblack@google.com// covered by patents for commercial use, please contact: 1912855Sgabeblack@google.com// Director of Intellectual Property Licensing 2012855Sgabeblack@google.com// Office of Strategy and Technology 2112855Sgabeblack@google.com// Hewlett-Packard Company 2212855Sgabeblack@google.com// 1501 Page Mill Road 2312855Sgabeblack@google.com// Palo Alto, California 94304 2412855Sgabeblack@google.com// 2512855Sgabeblack@google.com// Redistributions of source code must retain the above copyright notice, 2612855Sgabeblack@google.com// this list of conditions and the following disclaimer. Redistributions 2712855Sgabeblack@google.com// in binary form must reproduce the above copyright notice, this list of 2812855Sgabeblack@google.com// conditions and the following disclaimer in the documentation and/or 2912855Sgabeblack@google.com// other materials provided with the distribution. Neither the name of 3012855Sgabeblack@google.com// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 3112855Sgabeblack@google.com// contributors may be used to endorse or promote products derived from 3212855Sgabeblack@google.com// this software without specific prior written permission. No right of 3312855Sgabeblack@google.com// sublicense is granted herewith. Derivatives of the software and 3412855Sgabeblack@google.com// output created using the software may be prepared, but only for 3512855Sgabeblack@google.com// Non-Commercial Uses. Derivatives of the software may be shared with 3612855Sgabeblack@google.com// others provided: (i) the others agree to abide by the list of 3712855Sgabeblack@google.com// conditions herein which includes the Non-Commercial Use restrictions; 3812855Sgabeblack@google.com// and (ii) such Derivatives of the software include the above copyright 3912855Sgabeblack@google.com// notice to acknowledge the contribution from this software where 4012855Sgabeblack@google.com// applicable, this list of conditions and the disclaimer below. 4112855Sgabeblack@google.com// 4212855Sgabeblack@google.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4312855Sgabeblack@google.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 4412855Sgabeblack@google.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 4512855Sgabeblack@google.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 4612855Sgabeblack@google.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4712855Sgabeblack@google.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 4812855Sgabeblack@google.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 4912855Sgabeblack@google.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5012855Sgabeblack@google.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5112855Sgabeblack@google.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 5212855Sgabeblack@google.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5312855Sgabeblack@google.com// 5412855Sgabeblack@google.com// Authors: Gabe Black 5512855Sgabeblack@google.com 5612855Sgabeblack@google.com////////////////////////////////////////////////////////////////////////// 5712855Sgabeblack@google.com// 5812855Sgabeblack@google.com// LdStOp Microop templates 5912855Sgabeblack@google.com// 6012855Sgabeblack@google.com////////////////////////////////////////////////////////////////////////// 6112855Sgabeblack@google.com 6212855Sgabeblack@google.com// LEA template 6312855Sgabeblack@google.com 6412855Sgabeblack@google.comdef template MicroLeaExecute {{ 6512855Sgabeblack@google.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 6612855Sgabeblack@google.com Trace::InstRecord *traceData) const 6712855Sgabeblack@google.com { 6812855Sgabeblack@google.com Fault fault = NoFault; 6912855Sgabeblack@google.com Addr EA; 7012855Sgabeblack@google.com 7112855Sgabeblack@google.com %(op_decl)s; 7212855Sgabeblack@google.com %(op_rd)s; 7312855Sgabeblack@google.com %(ea_code)s; 7412855Sgabeblack@google.com DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 7512855Sgabeblack@google.com 7612855Sgabeblack@google.com %(code)s; 7712855Sgabeblack@google.com if(fault == NoFault) 7812855Sgabeblack@google.com { 7912855Sgabeblack@google.com %(op_wb)s; 8012855Sgabeblack@google.com } 8112855Sgabeblack@google.com 8212855Sgabeblack@google.com return fault; 8312855Sgabeblack@google.com } 8412855Sgabeblack@google.com}}; 8512855Sgabeblack@google.com 8612855Sgabeblack@google.comdef template MicroLeaDeclare {{ 8712855Sgabeblack@google.com class %(class_name)s : public %(base_class)s 8812855Sgabeblack@google.com { 8912855Sgabeblack@google.com 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 = read(xc, EA, Mem, (%(mem_flags)s) | segment); 127 128 if(fault == NoFault) 129 { 130 %(code)s; 131 } 132 if(fault == NoFault) 133 { 134 %(op_wb)s; 135 } 136 137 return fault; 138 } 139}}; 140 141def template MicroLoadInitiateAcc {{ 142 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 143 Trace::InstRecord * traceData) const 144 { 145 Fault fault = NoFault; 146 Addr EA; 147 148 %(op_decl)s; 149 %(op_rd)s; 150 %(ea_code)s; 151 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 152 153 fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); 154 155 return fault; 156 } 157}}; 158 159def template MicroLoadCompleteAcc {{ 160 Fault %(class_name)s::completeAcc(PacketPtr pkt, 161 %(CPU_exec_context)s * xc, 162 Trace::InstRecord * traceData) const 163 { 164 Fault fault = NoFault; 165 166 %(op_decl)s; 167 %(op_rd)s; 168 169 Mem = pkt->get<typeof(Mem)>(); 170 171 %(code)s; 172 173 if(fault == NoFault) 174 { 175 %(op_wb)s; 176 } 177 178 return fault; 179 } 180}}; 181 182// Store templates 183 184def template MicroStoreExecute {{ 185 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 186 Trace::InstRecord *traceData) const 187 { 188 Fault fault = NoFault; 189 190 Addr EA; 191 %(op_decl)s; 192 %(op_rd)s; 193 %(ea_code)s; 194 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 195 196 %(code)s; 197 198 if(fault == NoFault) 199 { 200 fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); 201 if(fault == NoFault) 202 { 203 %(op_wb)s; 204 } 205 } 206 207 return fault; 208 } 209}}; 210 211def template MicroStoreInitiateAcc {{ 212 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 213 Trace::InstRecord * traceData) const 214 { 215 Fault fault = NoFault; 216 217 Addr EA; 218 %(op_decl)s; 219 %(op_rd)s; 220 %(ea_code)s; 221 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 222 223 %(code)s; 224 225 if(fault == NoFault) 226 { 227 fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); 228 if(fault == NoFault) 229 { 230 %(op_wb)s; 231 } 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, addressSize): 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 = 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 = SegBase + scale * Index + Base + disp;" 360 361 def defineMicroLoadOp(mnemonic, code, mem_flags=0): 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, 372 "ea_code": calculateEA, 373 "mem_flags": mem_flags}) 374 header_output += MicroLdStOpDeclare.subst(iop) 375 decoder_output += MicroLdStOpConstructor.subst(iop) 376 exec_output += MicroLoadExecute.subst(iop) 377 exec_output += MicroLoadInitiateAcc.subst(iop) 378 exec_output += MicroLoadCompleteAcc.subst(iop) 379 380 class LoadOp(LdStOp): 381 def __init__(self, data, segment, addr, disp = 0, 382 dataSize="env.dataSize", addressSize="env.addressSize"): 383 super(LoadOp, self).__init__(data, segment, 384 addr, disp, dataSize, addressSize) 385 self.className = Name 386 self.mnemonic = name 387 388 microopClasses[name] = LoadOp 389 390 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 391 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck') 392 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') 393 394 def defineMicroStoreOp(mnemonic, code, mem_flags=0): 395 global header_output 396 global decoder_output 397 global exec_output 398 global microopClasses 399 Name = mnemonic 400 name = mnemonic.lower() 401 402 # Build up the all register version of this micro op 403 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 404 {"code": code, 405 "ea_code": calculateEA, 406 "mem_flags": mem_flags}) 407 header_output += MicroLdStOpDeclare.subst(iop) 408 decoder_output += MicroLdStOpConstructor.subst(iop) 409 exec_output += MicroStoreExecute.subst(iop) 410 exec_output += MicroStoreInitiateAcc.subst(iop) 411 exec_output += MicroStoreCompleteAcc.subst(iop) 412 413 class StoreOp(LdStOp): 414 def __init__(self, data, segment, addr, disp = 0, 415 dataSize="env.dataSize", addressSize="env.addressSize"): 416 super(StoreOp, self).__init__(data, segment, 417 addr, disp, dataSize, addressSize) 418 self.className = Name 419 self.mnemonic = name 420 421 microopClasses[name] = StoreOp 422 423 defineMicroStoreOp('St', 'Mem = Data;') 424 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') 425 defineMicroStoreOp('Stupd', ''' 426 Mem = Data; 427 Base = merge(Base, EA - SegBase, addressSize); 428 '''); 429 430 431 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 432 {"code": "Data = merge(Data, EA, dataSize);", 433 "ea_code": calculateEA, 434 "mem_flags": 0}) 435 header_output += MicroLeaDeclare.subst(iop) 436 decoder_output += MicroLdStOpConstructor.subst(iop) 437 exec_output += MicroLeaExecute.subst(iop) 438 439 class LeaOp(LdStOp): 440 def __init__(self, data, segment, addr, disp = 0, 441 dataSize="env.dataSize", addressSize="env.addressSize"): 442 super(LeaOp, self).__init__(data, segment, 443 addr, disp, dataSize, addressSize) 444 self.className = "Lea" 445 self.mnemonic = "lea" 446 447 microopClasses["lea"] = LeaOp 448 449 450 iop = InstObjParams("cda", "Cda", 'X86ISA::LdStOp', 451 {"code": ''' 452 Addr paddr; 453 fault = xc->translateDataWriteAddr(EA, paddr, 454 dataSize, (1 << segment)); 455 ''', 456 "ea_code": calculateEA}) 457 header_output += MicroLeaDeclare.subst(iop) 458 decoder_output += MicroLdStOpConstructor.subst(iop) 459 exec_output += MicroLeaExecute.subst(iop) 460 461 class CdaOp(LdStOp): 462 def __init__(self, segment, addr, disp = 0, 463 dataSize="env.dataSize", addressSize="env.addressSize"): 464 super(CdaOp, self).__init__("NUM_INTREGS", segment, 465 addr, disp, dataSize, addressSize) 466 self.className = "Cda" 467 self.mnemonic = "cda" 468 469 microopClasses["cda"] = CdaOp 470}}; 471 472