ldstop.isa revision 5175:ee904e392de2
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 = read(xc, EA, Mem, (%(mem_flags)s) | (1 << 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) | (1 << 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) | (1 << 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) | (1 << 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