regop.isa revision 4612
12914SN/A// Copyright (c) 2007 The Hewlett-Packard Development Company 210713Sandreas.hansson@arm.com// All rights reserved. 38856SN/A// 48856SN/A// Redistribution and use of this software in source and binary forms, 58856SN/A// with or without modification, are permitted provided that the 68856SN/A// following conditions are met: 78856SN/A// 88856SN/A// The software must be used only for Non-Commercial Use which means any 98856SN/A// use which is NOT directed to receiving any direct monetary 108856SN/A// compensation for, or commercial advantage from such use. Illustrative 118856SN/A// examples of non-commercial use are academic research, personal study, 128856SN/A// teaching, education and corporate research & development. 138856SN/A// Illustrative examples of commercial use are distributing products for 142914SN/A// commercial advantage and providing services using the software for 152914SN/A// commercial advantage. 162914SN/A// 172914SN/A// If you wish to use this software or functionality therein that may be 182914SN/A// covered by patents for commercial use, please contact: 192914SN/A// Director of Intellectual Property Licensing 202914SN/A// Office of Strategy and Technology 212914SN/A// Hewlett-Packard Company 222914SN/A// 1501 Page Mill Road 232914SN/A// Palo Alto, California 94304 242914SN/A// 252914SN/A// Redistributions of source code must retain the above copyright notice, 262914SN/A// this list of conditions and the following disclaimer. Redistributions 272914SN/A// in binary form must reproduce the above copyright notice, this list of 282914SN/A// conditions and the following disclaimer in the documentation and/or 292914SN/A// other materials provided with the distribution. Neither the name of 302914SN/A// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 312914SN/A// contributors may be used to endorse or promote products derived from 322914SN/A// this software without specific prior written permission. No right of 332914SN/A// sublicense is granted herewith. Derivatives of the software and 342914SN/A// output created using the software may be prepared, but only for 352914SN/A// Non-Commercial Uses. Derivatives of the software may be shared with 362914SN/A// others provided: (i) the others agree to abide by the list of 372914SN/A// conditions herein which includes the Non-Commercial Use restrictions; 382914SN/A// and (ii) such Derivatives of the software include the above copyright 392914SN/A// notice to acknowledge the contribution from this software where 402914SN/A// applicable, this list of conditions and the disclaimer below. 418856SN/A// 422914SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 432914SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 449356Snilay@cs.wisc.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 459152Satgutier@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 468914Sandreas.hansson@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 478914Sandreas.hansson@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 482914SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 495740SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 505740SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 518975Sandreas.hansson@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 5210913Sandreas.sandberg@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 535740SN/A// 545740SN/A// Authors: Gabe Black 555740SN/A 565740SN/A////////////////////////////////////////////////////////////////////////// 578914Sandreas.hansson@arm.com// 585740SN/A// RegOp Microop templates 595740SN/A// 605740SN/A////////////////////////////////////////////////////////////////////////// 618914Sandreas.hansson@arm.com 628914Sandreas.hansson@arm.comoutput header {{ 638914Sandreas.hansson@arm.com /** 648914Sandreas.hansson@arm.com * Base classes for RegOps which provides a generateDisassembly method. 658914Sandreas.hansson@arm.com */ 6610713Sandreas.hansson@arm.com class RegOp : public X86MicroopBase 678914Sandreas.hansson@arm.com { 688914Sandreas.hansson@arm.com protected: 698914Sandreas.hansson@arm.com const RegIndex src1; 704929SN/A const RegIndex src2; 7110713Sandreas.hansson@arm.com const RegIndex dest; 7210713Sandreas.hansson@arm.com const bool setStatus; 7310713Sandreas.hansson@arm.com const uint8_t dataSize; 7410713Sandreas.hansson@arm.com const uint8_t ext; 7510713Sandreas.hansson@arm.com 7610713Sandreas.hansson@arm.com // Constructor 7710713Sandreas.hansson@arm.com RegOp(ExtMachInst _machInst, 7810713Sandreas.hansson@arm.com const char *mnem, const char *_instMnem, 7910713Sandreas.hansson@arm.com bool isMicro, bool isDelayed, 8010713Sandreas.hansson@arm.com bool isFirst, bool isLast, 8110713Sandreas.hansson@arm.com RegIndex _src1, RegIndex _src2, RegIndex _dest, 8210713Sandreas.hansson@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext, 838914Sandreas.hansson@arm.com OpClass __opClass) : 843091SN/A X86MicroopBase(_machInst, mnem, _instMnem, 858856SN/A isMicro, isDelayed, isFirst, isLast, 868856SN/A __opClass), 8710322Sandreas.hansson@arm.com src1(_src1), src2(_src2), dest(_dest), 888856SN/A setStatus(_setStatus), dataSize(_dataSize), ext(_ext) 893296SN/A { 9010322Sandreas.hansson@arm.com } 918856SN/A 928856SN/A std::string generateDisassembly(Addr pc, 938856SN/A const SymbolTable *symtab) const; 948856SN/A }; 953284SN/A 964929SN/A class RegOpImm : public X86MicroopBase 978856SN/A { 988856SN/A protected: 998856SN/A const RegIndex src1; 1004490SN/A const uint8_t imm8; 1013342SN/A const RegIndex dest; 1024490SN/A const bool setStatus; 10310722Sstephan.diestelhorst@arm.com const uint8_t dataSize; 1043403SN/A const uint8_t ext; 10510722Sstephan.diestelhorst@arm.com 10610722Sstephan.diestelhorst@arm.com // Constructor 10710722Sstephan.diestelhorst@arm.com RegOpImm(ExtMachInst _machInst, 10810713Sandreas.hansson@arm.com const char * mnem, const char *_instMnem, 1099160Sandreas.hansson@arm.com bool isMicro, bool isDelayed, 1109160Sandreas.hansson@arm.com bool isFirst, bool isLast, 1114492SN/A RegIndex _src1, uint8_t _imm8, RegIndex _dest, 1129163Sandreas.hansson@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext, 1139163Sandreas.hansson@arm.com OpClass __opClass) : 1149163Sandreas.hansson@arm.com X86MicroopBase(_machInst, mnem, _instMnem, 1159390Sandreas.hansson@arm.com isMicro, isDelayed, isFirst, isLast, 1169390Sandreas.hansson@arm.com __opClass), 1179390Sandreas.hansson@arm.com src1(_src1), imm8(_imm8), dest(_dest), 1189390Sandreas.hansson@arm.com setStatus(_setStatus), dataSize(_dataSize), ext(_ext) 1199390Sandreas.hansson@arm.com { 1209390Sandreas.hansson@arm.com } 1219390Sandreas.hansson@arm.com 12210722Sstephan.diestelhorst@arm.com std::string generateDisassembly(Addr pc, 12310722Sstephan.diestelhorst@arm.com const SymbolTable *symtab) const; 12410722Sstephan.diestelhorst@arm.com }; 12510722Sstephan.diestelhorst@arm.com}}; 12610722Sstephan.diestelhorst@arm.com 12710722Sstephan.diestelhorst@arm.comoutput decoder {{ 12810722Sstephan.diestelhorst@arm.com std::string RegOp::generateDisassembly(Addr pc, 12910722Sstephan.diestelhorst@arm.com const SymbolTable *symtab) const 13010722Sstephan.diestelhorst@arm.com { 13110722Sstephan.diestelhorst@arm.com std::stringstream response; 13210722Sstephan.diestelhorst@arm.com 13310722Sstephan.diestelhorst@arm.com printMnemonic(response, instMnem, mnemonic); 13410722Sstephan.diestelhorst@arm.com printReg(response, dest); 13510722Sstephan.diestelhorst@arm.com response << ", "; 13610722Sstephan.diestelhorst@arm.com printReg(response, src1); 1378914Sandreas.hansson@arm.com response << ", "; 1388914Sandreas.hansson@arm.com printReg(response, src2); 1394666SN/A return response.str(); 14010722Sstephan.diestelhorst@arm.com } 14110722Sstephan.diestelhorst@arm.com 1428914Sandreas.hansson@arm.com std::string RegOpImm::generateDisassembly(Addr pc, 1438914Sandreas.hansson@arm.com const SymbolTable *symtab) const 1448914Sandreas.hansson@arm.com { 14510922Sandreas.hansson@arm.com std::stringstream response; 1464666SN/A 1474666SN/A printMnemonic(response, instMnem, mnemonic); 1484666SN/A printReg(response, dest); 1494666SN/A response << ", "; 15010713Sandreas.hansson@arm.com printReg(response, src1); 15110713Sandreas.hansson@arm.com ccprintf(response, ", %#x", imm8); 15210713Sandreas.hansson@arm.com return response.str(); 15310713Sandreas.hansson@arm.com } 15410713Sandreas.hansson@arm.com}}; 15510713Sandreas.hansson@arm.com 15610713Sandreas.hansson@arm.comdef template MicroRegOpExecute {{ 15710713Sandreas.hansson@arm.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1588914Sandreas.hansson@arm.com Trace::InstRecord *traceData) const 1594666SN/A { 16010922Sandreas.hansson@arm.com Fault fault = NoFault; 1613450SN/A 1623403SN/A %(op_decl)s; 1633450SN/A %(op_rd)s; 16410722Sstephan.diestelhorst@arm.com %(code)s; 16510722Sstephan.diestelhorst@arm.com %(flag_code)s; 16610722Sstephan.diestelhorst@arm.com 1678914Sandreas.hansson@arm.com //Write the resulting state to the execution context 16810322Sandreas.hansson@arm.com if(fault == NoFault) 1698914Sandreas.hansson@arm.com { 1708914Sandreas.hansson@arm.com %(op_wb)s; 1718914Sandreas.hansson@arm.com } 17210922Sandreas.hansson@arm.com return fault; 1738856SN/A } 1748856SN/A}}; 1758856SN/A 17610713Sandreas.hansson@arm.comdef template MicroRegOpImmExecute {{ 1778856SN/A Fault %(class_name)sImm::execute(%(CPU_exec_context)s *xc, 17810713Sandreas.hansson@arm.com Trace::InstRecord *traceData) const 17910713Sandreas.hansson@arm.com { 18010713Sandreas.hansson@arm.com Fault fault = NoFault; 18110713Sandreas.hansson@arm.com 18210713Sandreas.hansson@arm.com %(op_decl)s; 18310713Sandreas.hansson@arm.com %(op_rd)s; 1848914Sandreas.hansson@arm.com %(code)s; 18510713Sandreas.hansson@arm.com %(flag_code)s; 18610713Sandreas.hansson@arm.com 18710713Sandreas.hansson@arm.com //Write the resulting state to the execution context 18810713Sandreas.hansson@arm.com if(fault == NoFault) 18910713Sandreas.hansson@arm.com { 19010713Sandreas.hansson@arm.com %(op_wb)s; 19110423Sandreas.hansson@arm.com } 19210713Sandreas.hansson@arm.com return fault; 19310713Sandreas.hansson@arm.com } 19410423Sandreas.hansson@arm.com}}; 19510423Sandreas.hansson@arm.com 19610713Sandreas.hansson@arm.comdef template MicroRegOpDeclare {{ 19710423Sandreas.hansson@arm.com class %(class_name)s : public %(base_class)s 1988856SN/A { 19910713Sandreas.hansson@arm.com protected: 20010713Sandreas.hansson@arm.com void buildMe(); 20110913Sandreas.sandberg@arm.com 20210913Sandreas.sandberg@arm.com public: 20310913Sandreas.sandberg@arm.com %(class_name)s(ExtMachInst _machInst, 2049152Satgutier@umich.edu const char * instMnem, 2059152Satgutier@umich.edu bool isMicro, bool isDelayed, bool isFirst, bool isLast, 20610913Sandreas.sandberg@arm.com RegIndex _src1, RegIndex _src2, RegIndex _dest, 2078856SN/A bool _setStatus, uint8_t _dataSize, uint8_t _ext); 2088856SN/A 2098856SN/A %(class_name)s(ExtMachInst _machInst, 2104492SN/A const char * instMnem, 2113403SN/A RegIndex _src1, RegIndex _src2, RegIndex _dest, 2128914Sandreas.hansson@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext); 2132914SN/A 21410713Sandreas.hansson@arm.com %(BasicExecDeclare)s 21510713Sandreas.hansson@arm.com }; 21610713Sandreas.hansson@arm.com}}; 21710713Sandreas.hansson@arm.com 21810713Sandreas.hansson@arm.comdef template MicroRegOpImmDeclare {{ 21910713Sandreas.hansson@arm.com 22010713Sandreas.hansson@arm.com class %(class_name)sImm : public %(base_class)s 22110713Sandreas.hansson@arm.com { 22210713Sandreas.hansson@arm.com protected: 22310713Sandreas.hansson@arm.com void buildMe(); 22410713Sandreas.hansson@arm.com 22510713Sandreas.hansson@arm.com public: 22610713Sandreas.hansson@arm.com %(class_name)sImm(ExtMachInst _machInst, 22710713Sandreas.hansson@arm.com const char * instMnem, 22810713Sandreas.hansson@arm.com bool isMicro, bool isDelayed, bool isFirst, bool isLast, 22910713Sandreas.hansson@arm.com RegIndex _src1, uint8_t _imm8, RegIndex _dest, 2304492SN/A bool _setStatus, uint8_t _dataSize, uint8_t _ext); 2318856SN/A 2328856SN/A %(class_name)sImm(ExtMachInst _machInst, 2338856SN/A const char * instMnem, 23410713Sandreas.hansson@arm.com RegIndex _src1, uint8_t _imm8, RegIndex _dest, 23510713Sandreas.hansson@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext); 23610713Sandreas.hansson@arm.com 23710745Sandreas.hansson@arm.com %(BasicExecDeclare)s 2384492SN/A }; 2394492SN/A}}; 2404492SN/A 2414492SN/Adef template MicroRegOpConstructor {{ 2428914Sandreas.hansson@arm.com 2434492SN/A inline void %(class_name)s::buildMe() 2444492SN/A { 2454492SN/A %(constructor)s; 2462914SN/A } 2472914SN/A 24810913Sandreas.sandberg@arm.com inline %(class_name)s::%(class_name)s( 24910913Sandreas.sandberg@arm.com ExtMachInst machInst, const char * instMnem, 2502914SN/A RegIndex _src1, RegIndex _src2, RegIndex _dest, 25110913Sandreas.sandberg@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 25210913Sandreas.sandberg@arm.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, 25310913Sandreas.sandberg@arm.com false, false, false, false, 25410913Sandreas.sandberg@arm.com _src1, _src2, _dest, _setStatus, _dataSize, _ext, 25510913Sandreas.sandberg@arm.com %(op_class)s) 25610913Sandreas.sandberg@arm.com { 2572914SN/A buildMe(); 2588975Sandreas.hansson@arm.com } 25910713Sandreas.hansson@arm.com 26010713Sandreas.hansson@arm.com inline %(class_name)s::%(class_name)s( 2618975Sandreas.hansson@arm.com ExtMachInst machInst, const char * instMnem, 2628975Sandreas.hansson@arm.com bool isMicro, bool isDelayed, bool isFirst, bool isLast, 2638975Sandreas.hansson@arm.com RegIndex _src1, RegIndex _src2, RegIndex _dest, 2648975Sandreas.hansson@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 2658975Sandreas.hansson@arm.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, 26610713Sandreas.hansson@arm.com isMicro, isDelayed, isFirst, isLast, 2678975Sandreas.hansson@arm.com _src1, _src2, _dest, _setStatus, _dataSize, _ext, 26810713Sandreas.hansson@arm.com %(op_class)s) 2698975Sandreas.hansson@arm.com { 2708975Sandreas.hansson@arm.com buildMe(); 27110713Sandreas.hansson@arm.com } 27210713Sandreas.hansson@arm.com}}; 27310713Sandreas.hansson@arm.com 27410713Sandreas.hansson@arm.comdef template MicroRegOpImmConstructor {{ 27510713Sandreas.hansson@arm.com 27610713Sandreas.hansson@arm.com inline void %(class_name)sImm::buildMe() 27710713Sandreas.hansson@arm.com { 27810713Sandreas.hansson@arm.com %(constructor)s; 27910713Sandreas.hansson@arm.com } 28010713Sandreas.hansson@arm.com 28110713Sandreas.hansson@arm.com inline %(class_name)sImm::%(class_name)sImm( 28210713Sandreas.hansson@arm.com ExtMachInst machInst, const char * instMnem, 28310713Sandreas.hansson@arm.com RegIndex _src1, uint8_t _imm8, RegIndex _dest, 28410713Sandreas.hansson@arm.com bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 28510713Sandreas.hansson@arm.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, 2868975Sandreas.hansson@arm.com false, false, false, false, 2878975Sandreas.hansson@arm.com _src1, _imm8, _dest, _setStatus, _dataSize, _ext, 2888975Sandreas.hansson@arm.com %(op_class)s) 2898975Sandreas.hansson@arm.com { 2908975Sandreas.hansson@arm.com buildMe(); 29110713Sandreas.hansson@arm.com } 2928975Sandreas.hansson@arm.com 2938975Sandreas.hansson@arm.com inline %(class_name)sImm::%(class_name)sImm( 2948975Sandreas.hansson@arm.com ExtMachInst machInst, const char * instMnem, 295 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 296 RegIndex _src1, uint8_t _imm8, RegIndex _dest, 297 bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 298 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 299 isMicro, isDelayed, isFirst, isLast, 300 _src1, _imm8, _dest, _setStatus, _dataSize, _ext, 301 %(op_class)s) 302 { 303 buildMe(); 304 } 305}}; 306 307let {{ 308 class RegOp(X86Microop): 309 def __init__(self, dest, src1, src2, setStatus): 310 self.dest = dest 311 self.src1 = src1 312 self.src2 = src2 313 self.setStatus = setStatus 314 self.dataSize = "env.dataSize" 315 self.ext = 0 316 317 def getAllocator(self, *microFlags): 318 allocator = '''new %(class_name)s(machInst, mnemonic 319 %(flags)s, %(src1)s, %(src2)s, %(dest)s, 320 %(setStatus)s, %(dataSize)s, %(ext)s)''' % { 321 "class_name" : self.className, 322 "flags" : self.microFlagsText(microFlags), 323 "src1" : self.src1, "src2" : self.src2, 324 "dest" : self.dest, 325 "setStatus" : self.cppBool(self.setStatus), 326 "dataSize" : self.dataSize, 327 "ext" : self.ext} 328 return allocator 329 330 class RegOpImm(X86Microop): 331 def __init__(self, dest, src1, imm8, setStatus): 332 self.dest = dest 333 self.src1 = src1 334 self.imm8 = imm8 335 self.setStatus = setStatus 336 self.dataSize = "env.dataSize" 337 self.ext = 0 338 339 def getAllocator(self, *microFlags): 340 allocator = '''new %(class_name)s(machInst, mnemonic 341 %(flags)s, %(src1)s, %(imm8)s, %(dest)s, 342 %(setStatus)s, %(dataSize)s, %(ext)s)''' % { 343 "class_name" : self.className, 344 "flags" : self.microFlagsText(microFlags), 345 "src1" : self.src1, "imm8" : self.imm8, 346 "dest" : self.dest, 347 "setStatus" : self.cppBool(self.setStatus), 348 "dataSize" : self.dataSize, 349 "ext" : self.ext} 350 return allocator 351}}; 352 353let {{ 354 355 # Make these empty strings so that concatenating onto 356 # them will always work. 357 header_output = "" 358 decoder_output = "" 359 exec_output = "" 360 361 def setUpMicroRegOp(name, Name, base, code, child, flagCode): 362 global header_output 363 global decoder_output 364 global exec_output 365 global microopClasses 366 367 iop = InstObjParams(name, Name, base, 368 {"code" : code, 369 "flag_code" : flagCode}) 370 header_output += MicroRegOpDeclare.subst(iop) 371 decoder_output += MicroRegOpConstructor.subst(iop) 372 exec_output += MicroRegOpExecute.subst(iop) 373 374 microopClasses[name] = child 375 376 def defineMicroRegOp(mnemonic, code, flagCode): 377 Name = mnemonic 378 name = mnemonic.lower() 379 380 # Find op2 in each of the instruction definitions. Create two versions 381 # of the code, one with an integer operand, and one with an immediate 382 # operand. 383 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 384 regCode = matcher.sub("SrcReg2", code) 385 immCode = matcher.sub("imm8", code) 386 387 # Build the all register version of this micro op 388 class RegOpChild(RegOp): 389 def __init__(self, dest, src1, src2, setStatus=False): 390 super(RegOpChild, self).__init__(dest, src1, src2, setStatus) 391 self.className = Name 392 self.mnemonic = name 393 394 setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode); 395 396 # Build the immediate version of this micro op 397 class RegOpChildImm(RegOpImm): 398 def __init__(self, dest, src1, src2, setStatus=False): 399 super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus) 400 self.className = Name + "Imm" 401 self.mnemonic = name + "i" 402 403 setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode); 404 405 defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF 406 defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "") 407 defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF 408 defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF 409 defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "") 410 defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF 411 defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "") 412 defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg 413 defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "") 414 415 # This has it's own function because Wr ops have implicit destinations 416 def defineMicroRegOpWr(mnemonic, code): 417 Name = mnemonic 418 name = mnemonic.lower() 419 420 # Find op2 in each of the instruction definitions. Create two versions 421 # of the code, one with an integer operand, and one with an immediate 422 # operand. 423 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 424 regCode = matcher.sub("SrcReg2", code) 425 immCode = matcher.sub("imm8", code) 426 427 # Build the all register version of this micro op 428 class RegOpChild(RegOp): 429 def __init__(self, src1, src2): 430 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False) 431 self.className = Name 432 self.mnemonic = name 433 434 setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, ""); 435 436 # Build the immediate version of this micro op 437 class RegOpChildImm(RegOpImm): 438 def __init__(self, src1, src2): 439 super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False) 440 self.className = Name + "Imm" 441 self.mnemonic = name + "i" 442 443 setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, ""); 444 445 defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2') 446 447 # This has it's own function because Rd ops don't always have two parameters 448 def defineMicroRegOpRd(mnemonic, code): 449 Name = mnemonic 450 name = mnemonic.lower() 451 452 class RegOpChild(RegOp): 453 def __init__(self, dest, src1 = "NUM_INTREGS"): 454 super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False) 455 self.className = Name 456 self.mnemonic = name 457 458 setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, ""); 459 460 defineMicroRegOpRd('Rdip', 'DestReg = RIP') 461 462 def defineMicroRegOpImm(mnemonic, code): 463 Name = mnemonic 464 name = mnemonic.lower() 465 466 class RegOpChild(RegOpImm): 467 def __init__(self, dest, src1, src2): 468 super(RegOpChild, self).__init__(dest, src1, src2, False) 469 self.className = Name 470 self.mnemonic = name 471 472 setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, ""); 473 474 defineMicroRegOpImm('Sext', ''' 475 IntReg val = SrcReg1; 476 int sign_bit = bits(val, imm8-1, imm8-1); 477 val = sign_bit ? (val | ~mask(imm8)) : val; 478 DestReg = merge(DestReg, val, dataSize);''') 479}}; 480