regop.isa (5032:17f771e6b2f2) | regop.isa (5040:126e4510b5bb) |
---|---|
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 --- 214 unchanged lines hidden (view full) --- 223 _src1, _imm8, _dest, _dataSize, _ext, 224 %(op_class)s) 225 { 226 buildMe(); 227 } 228}}; 229 230let {{ | 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 --- 214 unchanged lines hidden (view full) --- 223 _src1, _imm8, _dest, _dataSize, _ext, 224 %(op_class)s) 225 { 226 buildMe(); 227 } 228}}; 229 230let {{ |
231 class X86MicroMeta(type): 232 def __new__(mcls, name, bases, dict): | 231 # Make these empty strings so that concatenating onto 232 # them will always work. 233 header_output = "" 234 decoder_output = "" 235 exec_output = "" 236 237 immTemplates = ( 238 MicroRegOpImmDeclare, 239 MicroRegOpImmConstructor, 240 MicroRegOpImmExecute) 241 242 regTemplates = ( 243 MicroRegOpDeclare, 244 MicroRegOpConstructor, 245 MicroRegOpExecute) 246 247 class RegOpMeta(type): 248 def buildCppClasses(self, name, Name, suffix, \ 249 code, flag_code, cond_check, else_code): 250 251 # Globals to stick the output in 252 global header_output 253 global decoder_output 254 global exec_output 255 256 # Stick all the code together so it can be searched at once 257 allCode = "|".join((code, flag_code, cond_check, else_code)) 258 259 # If op2 is used anywhere, make register and immediate versions 260 # of this code. 261 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 262 if matcher.search(allCode): 263 self.buildCppClasses(name, Name, suffix, 264 matcher.sub("psrc2", code), 265 matcher.sub("psrc2", flag_code), 266 matcher.sub("psrc2", cond_check), 267 matcher.sub("psrc2", else_code)) 268 self.buildCppClasses(name + "i", Name, suffix + "Imm", 269 matcher.sub("imm8", code), 270 matcher.sub("imm8", flag_code), 271 matcher.sub("imm8", cond_check), 272 matcher.sub("imm8", else_code)) 273 return 274 275 # If there's something optional to do with flags, generate 276 # a version without it and fix up this version to use it. 277 if flag_code is not "" or cond_check is not "true": 278 self.buildCppClasses(name, Name, suffix, 279 code, "", "true", else_code) 280 suffix = "Flags" + suffix 281 282 # If psrc1 or psrc2 is used, we need to actually insert code to 283 # compute it. 284 matcher = re.compile("(?<!\w)psrc1(?!\w)") 285 if matcher.search(allCode): 286 code = "IntReg psrc1 = pick(SrcReg1, 0, dataSize);" + code 287 matcher = re.compile("(?<!\w)psrc2(?!\w)") 288 if matcher.search(allCode): 289 code = "IntReg psrc2 = pick(SrcReg2, 1, dataSize);" + code 290 291 base = "X86ISA::RegOp" 292 293 # If imm8 shows up in the code, use the immediate templates, if 294 # not, hopefully the register ones will be correct. 295 templates = regTemplates 296 matcher = re.compile("(?<!\w)imm8(?!\w)") 297 if matcher.search(allCode): 298 base += "Imm" 299 templates = immTemplates 300 301 # Get everything ready for the substitution 302 iop = InstObjParams(name, Name + suffix, base, 303 {"code" : code, 304 "flag_code" : flag_code, 305 "cond_check" : cond_check, 306 "else_code" : else_code}) 307 308 # Generate the actual code (finally!) 309 header_output += templates[0].subst(iop) 310 decoder_output += templates[1].subst(iop) 311 exec_output += templates[2].subst(iop) 312 313 314 def __new__(mcls, Name, bases, dict): |
233 abstract = False | 315 abstract = False |
316 name = Name.lower() |
|
234 if "abstract" in dict: 235 abstract = dict['abstract'] 236 del dict['abstract'] 237 | 317 if "abstract" in dict: 318 abstract = dict['abstract'] 319 del dict['abstract'] 320 |
238 cls = type.__new__(mcls, name, bases, dict) | 321 cls = super(RegOpMeta, mcls).__new__(mcls, Name, bases, dict) |
239 if not abstract: | 322 if not abstract: |
240 allClasses[name] = cls | 323 cls.className = Name 324 cls.base_mnemonic = name 325 code = cls.code 326 flag_code = cls.flag_code 327 cond_check = cls.cond_check 328 else_code = cls.else_code 329 330 # Set up the C++ classes 331 mcls.buildCppClasses(cls, name, Name, "", 332 code, flag_code, cond_check, else_code) 333 334 # Hook into the microassembler dict 335 global microopClasses 336 microopClasses[name] = cls 337 338 allCode = "|".join((code, flag_code, cond_check, else_code)) 339 340 # If op2 is used anywhere, make register and immediate versions 341 # of this code. 342 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 343 if matcher.search(allCode): 344 microopClasses[name + 'i'] = cls |
241 return cls 242 | 345 return cls 346 |
243 class XXX86Microop(object): 244 __metaclass__ = X86MicroMeta 245 abstract = True | |
246 247 class RegOp(X86Microop): | 347 348 class RegOp(X86Microop): |
349 __metaclass__ = RegOpMeta 350 # This class itself doesn't act as a microop |
|
248 abstract = True | 351 abstract = True |
249 def __init__(self, dest, src1, src2, flags, dataSize): 250 self.dest = dest 251 self.src1 = src1 252 self.src2 = src2 253 self.flags = flags 254 self.dataSize = dataSize 255 if flags is None: 256 self.ext = 0 257 else: 258 if not isinstance(flags, (list, tuple)): 259 raise Exception, "flags must be a list or tuple of flags" 260 self.ext = " | ".join(flags) 261 self.className += "Flags" | |
262 | 352 |
263 def getAllocator(self, *microFlags): 264 allocator = '''new %(class_name)s(machInst, mnemonic 265 %(flags)s, %(src1)s, %(src2)s, %(dest)s, 266 %(dataSize)s, %(ext)s)''' % { 267 "class_name" : self.className, 268 "flags" : self.microFlagsText(microFlags), 269 "src1" : self.src1, "src2" : self.src2, 270 "dest" : self.dest, 271 "dataSize" : self.dataSize, 272 "ext" : self.ext} 273 return allocator | 353 # Default template parameter values 354 flag_code = "" 355 cond_check = "true" 356 else_code = ";" |
274 | 357 |
275 class RegOpImm(X86Microop): 276 abstract = True 277 def __init__(self, dest, src1, imm8, flags, dataSize): | 358 def __init__(self, dest, src1, op2, flags = None, dataSize = "env.dataSize"): |
278 self.dest = dest 279 self.src1 = src1 | 359 self.dest = dest 360 self.src1 = src1 |
280 self.imm8 = imm8 | 361 self.op2 = op2 |
281 self.flags = flags 282 self.dataSize = dataSize 283 if flags is None: 284 self.ext = 0 285 else: 286 if not isinstance(flags, (list, tuple)): 287 raise Exception, "flags must be a list or tuple of flags" 288 self.ext = " | ".join(flags) 289 self.className += "Flags" 290 291 def getAllocator(self, *microFlags): | 362 self.flags = flags 363 self.dataSize = dataSize 364 if flags is None: 365 self.ext = 0 366 else: 367 if not isinstance(flags, (list, tuple)): 368 raise Exception, "flags must be a list or tuple of flags" 369 self.ext = " | ".join(flags) 370 self.className += "Flags" 371 372 def getAllocator(self, *microFlags): |
373 className = self.className 374 if self.mnemonic == self.base_mnemonic + 'i': 375 className += "Imm" |
|
292 allocator = '''new %(class_name)s(machInst, mnemonic | 376 allocator = '''new %(class_name)s(machInst, mnemonic |
293 %(flags)s, %(src1)s, %(imm8)s, %(dest)s, | 377 %(flags)s, %(src1)s, %(op2)s, %(dest)s, |
294 %(dataSize)s, %(ext)s)''' % { | 378 %(dataSize)s, %(ext)s)''' % { |
295 "class_name" : self.className, | 379 "class_name" : className, |
296 "flags" : self.microFlagsText(microFlags), | 380 "flags" : self.microFlagsText(microFlags), |
297 "src1" : self.src1, "imm8" : self.imm8, | 381 "src1" : self.src1, "op2" : self.op2, |
298 "dest" : self.dest, 299 "dataSize" : self.dataSize, 300 "ext" : self.ext} 301 return allocator | 382 "dest" : self.dest, 383 "dataSize" : self.dataSize, 384 "ext" : self.ext} 385 return allocator |
302}}; | |
303 | 386 |
304let {{ | 387 class LogicRegOp(RegOp): 388 abstract = True 389 flag_code = ''' 390 //Don't have genFlags handle the OF or CF bits 391 uint64_t mask = CFBit | OFBit; 392 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2); 393 //If a logic microop wants to set these, it wants to set them to 0. 394 ccFlagBits &= ~(CFBit & ext); 395 ccFlagBits &= ~(OFBit & ext); 396 ''' |
305 | 397 |
306 # Make these empty strings so that concatenating onto 307 # them will always work. 308 header_output = "" 309 decoder_output = "" 310 exec_output = "" | 398 class FlagRegOp(RegOp): 399 abstract = True 400 flag_code = \ 401 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);" |
311 | 402 |
312 # A function which builds the C++ classes that implement the microops 313 def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";", imm=False): 314 global header_output 315 global decoder_output 316 global exec_output 317 global microopClasses | 403 class SubRegOp(RegOp): 404 abstract = True 405 flag_code = \ 406 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);" |
318 | 407 |
319 iop = InstObjParams(name, Name, base, 320 {"code" : code, 321 "flag_code" : flagCode, 322 "cond_check" : condCheck, 323 "else_code" : elseCode}) 324 if imm: 325 header_output += MicroRegOpImmDeclare.subst(iop) 326 decoder_output += MicroRegOpImmConstructor.subst(iop) 327 exec_output += MicroRegOpImmExecute.subst(iop) 328 else: 329 header_output += MicroRegOpDeclare.subst(iop) 330 decoder_output += MicroRegOpConstructor.subst(iop) 331 exec_output += MicroRegOpExecute.subst(iop) | 408 class CondRegOp(RegOp): 409 abstract = True 410 cond_check = "checkCondition(ccFlagBits)" |
332 | 411 |
412 class Add(FlagRegOp): 413 code = 'DestReg = merge(DestReg, psrc1 + op2, dataSize);' |
|
333 | 414 |
334 checkCCFlagBits = "checkCondition(ccFlagBits)" 335 genCCFlagBits = \ 336 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);" 337 genCCFlagBitsSub = \ 338 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);" 339 genCCFlagBitsLogic = ''' 340 //Don't have genFlags handle the OF or CF bits 341 uint64_t mask = CFBit | OFBit; 342 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2); 343 //If a logic microop wants to set these, it wants to set them to 0. 344 ccFlagBits &= ~(CFBit & ext); 345 ccFlagBits &= ~(OFBit & ext); 346 ''' | 415 class Or(LogicRegOp): 416 code = 'DestReg = merge(DestReg, psrc1 | op2, dataSize);' |
347 | 417 |
348 regPick = ''' 349 IntReg psrc1 = pick(SrcReg1, 0, dataSize); 350 IntReg psrc2 = pick(SrcReg2, 1, dataSize); 351 ''' 352 immPick = ''' 353 IntReg psrc1 = pick(SrcReg1, 0, dataSize); 354 ''' | 418 class Adc(FlagRegOp): 419 code = ''' 420 CCFlagBits flags = ccFlagBits; 421 DestReg = merge(DestReg, psrc1 + op2 + flags.CF, dataSize); 422 ''' |
355 | 423 |
424 class Sbb(SubRegOp): 425 code = ''' 426 CCFlagBits flags = ccFlagBits; 427 DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize); 428 ''' |
|
356 | 429 |
357 # This creates a python representations of a microop which are a cross 358 # product of reg/immediate and flag/no flag versions. 359 def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \ 360 cc=False, doImm=True, elseCode=";"): 361 Name = mnemonic 362 name = mnemonic.lower() | 430 class And(LogicRegOp): 431 code = 'DestReg = merge(DestReg, psrc1 & op2, dataSize)' |
363 | 432 |
364 # Find op2 in each of the instruction definitions. Create two versions 365 # of the code, one with an integer operand, and one with an immediate 366 # operand. 367 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 368 regCode = regPick + matcher.sub("psrc2", code) 369 immCode = immPick + matcher.sub("imm8", code) | 433 class Sub(SubRegOp): 434 code = 'DestReg = merge(DestReg, psrc1 - op2, dataSize)' |
370 | 435 |
371 if not cc: 372 condCode = "true" 373 else: 374 flagCode = "" 375 condCode = checkCCFlagBits | 436 class Xor(LogicRegOp): 437 code = 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)' |
376 | 438 |
377 regFlagCode = matcher.sub("psrc2", flagCode) 378 immFlagCode = matcher.sub("imm8", flagCode) 379 380 class RegOpChild(RegOp): 381 mnemonic = name 382 className = Name 383 def __init__(self, dest, src1, src2, \ 384 flags=None, dataSize="env.dataSize"): 385 super(RegOpChild, self).__init__(dest, src1, src2, \ 386 flags, dataSize) 387 388 microopClasses[name] = RegOpChild 389 390 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode); 391 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", 392 regCode, flagCode=regFlagCode, 393 condCheck=condCode, elseCode=elseCode); 394 395 if doImm: 396 class RegOpChildImm(RegOpImm): 397 mnemonic = name + 'i' 398 className = Name + 'Imm' 399 def __init__(self, dest, src1, src2, \ 400 flags=None, dataSize="env.dataSize"): 401 super(RegOpChildImm, self).__init__(dest, src1, src2, \ 402 flags, dataSize) 403 404 microopClasses[name + 'i'] = RegOpChildImm 405 406 setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \ 407 immCode, imm=True); 408 setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", 409 immCode, flagCode=immFlagCode, 410 condCheck=condCode, elseCode=elseCode, imm=True); 411 412 # This has it's own function because Wr ops have implicit destinations 413 def defineMicroRegOpWr(mnemonic, code, elseCode=";"): 414 Name = mnemonic 415 name = mnemonic.lower() 416 417 # Find op2 in each of the instruction definitions. Create two versions 418 # of the code, one with an integer operand, and one with an immediate 419 # operand. 420 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 421 regCode = regPick + matcher.sub("psrc2", code) 422 immCode = immPick + matcher.sub("imm8", code) 423 424 class RegOpChild(RegOp): 425 mnemonic = name 426 className = Name 427 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): 428 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) 429 430 microopClasses[name] = RegOpChild 431 432 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode); 433 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, 434 condCheck = checkCCFlagBits, elseCode = elseCode); 435 436 class RegOpChildImm(RegOpImm): 437 mnemonic = name + 'i' 438 className = Name + 'Imm' 439 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): 440 super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) 441 442 microopClasses[name + 'i'] = RegOpChildImm 443 444 setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", \ 445 immCode, imm=True); 446 setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", \ 447 immCode, condCheck = checkCCFlagBits, elseCode = elseCode, \ 448 imm=True); 449 450 # This has it's own function because Rd ops don't always have two parameters 451 def defineMicroRegOpRd(mnemonic, code): 452 Name = mnemonic 453 name = mnemonic.lower() 454 455 class RegOpChild(RegOp): 456 className = Name 457 mnemonic = name 458 def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"): 459 super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize) 460 461 microopClasses[name] = RegOpChild 462 463 setUpMicroRegOp(name, Name, "X86ISA::RegOp", code); 464 465 def defineMicroRegOpImm(mnemonic, code, flagCode=""): 466 Name = mnemonic 467 name = mnemonic.lower() 468 code = immPick + code 469 470 class RegOpChild(RegOpImm): 471 className = Name 472 mnemonic = name 473 def __init__(self, dest, src1, src2, \ 474 flags=None, dataSize="env.dataSize"): 475 super(RegOpChild, self).__init__(dest, \ 476 src1, src2, flags, dataSize) 477 478 microopClasses[name] = RegOpChild 479 480 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, imm=True); 481 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOpImm", \ 482 code, flagCode=flagCode, imm=True); 483 484 def defineMicroRegOpRdImm(mnemonic, code, flagCode=""): 485 Name = mnemonic 486 name = mnemonic.lower() 487 code = immPick + code 488 489 class RegOpChildRdImm(RegOpImm): 490 className = Name 491 mnemonic = name 492 def __init__(self, dest, imm, flags=None, \ 493 dataSize="env.dataSize"): 494 super(RegOpChildRdImm, self).__init__(dest, \ 495 "NUM_INTREGS", imm, flags, dataSize) 496 497 microopClasses[name] = RegOpChildRdImm 498 499 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, imm=True); 500 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOpImm", \ 501 code, flagCode=flagCode, imm=True); 502 503 defineMicroRegOp('Add', 'DestReg = merge(DestReg, psrc1 + op2, dataSize)') 504 defineMicroRegOp('Or', 'DestReg = merge(DestReg, psrc1 | op2, dataSize);', 505 flagCode = genCCFlagBitsLogic) 506 defineMicroRegOp('Adc', ''' 507 CCFlagBits flags = ccFlagBits; 508 DestReg = merge(DestReg, psrc1 + op2 + flags.CF, dataSize); 509 ''') 510 defineMicroRegOp('Sbb', ''' 511 CCFlagBits flags = ccFlagBits; 512 DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize); 513 ''', flagCode = genCCFlagBitsSub) 514 defineMicroRegOp('And', \ 515 'DestReg = merge(DestReg, psrc1 & op2, dataSize)', \ 516 flagCode = genCCFlagBitsLogic) 517 defineMicroRegOp('Sub', \ 518 'DestReg = merge(DestReg, psrc1 - op2, dataSize)', \ 519 flagCode = genCCFlagBitsSub) 520 defineMicroRegOp('Xor', \ 521 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)', \ 522 flagCode = genCCFlagBitsLogic) 523 defineMicroRegOp('Mul1s', ''' | 439 class Mul1s(FlagRegOp): 440 code = ''' |
524 int signPos = (dataSize * 8) / 2 - 1; 525 IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos); 526 IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos); 527 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize) | 441 int signPos = (dataSize * 8) / 2 - 1; 442 IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos); 443 IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos); 444 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize) |
528 ''') 529 defineMicroRegOp('Mul1u', ''' | 445 ''' 446 447 class Mul1u(FlagRegOp): 448 code = ''' |
530 int halfSize = (dataSize * 8) / 2; 531 IntReg srcVal1 = psrc1 & mask(halfSize); 532 IntReg srcVal2 = op2 & mask(halfSize); 533 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize) | 449 int halfSize = (dataSize * 8) / 2; 450 IntReg srcVal1 = psrc1 & mask(halfSize); 451 IntReg srcVal2 = op2 & mask(halfSize); 452 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize) |
534 ''') 535 defineMicroRegOp('Mulel', \ 536 'DestReg = merge(DestReg, psrc1 * op2, dataSize)') 537 defineMicroRegOp('Muleh', ''' | 453 ''' 454 455 class Mulel(FlagRegOp): 456 code = 'DestReg = merge(DestReg, psrc1 * op2, dataSize)' 457 458 class Muleh(FlagRegOp): 459 code = ''' |
538 int halfSize = (dataSize * 8) / 2; 539 uint64_t psrc1_h = psrc1 >> halfSize; 540 uint64_t psrc1_l = psrc1 & mask(halfSize); 541 uint64_t psrc2_h = op2 >> halfSize; 542 uint64_t psrc2_l = op2 & mask(halfSize); 543 uint64_t result = 544 ((psrc1_l * psrc2_h) >> halfSize) + 545 ((psrc1_h * psrc2_l) >> halfSize) + 546 psrc1_h * psrc2_h; 547 DestReg = merge(DestReg, result, dataSize); | 460 int halfSize = (dataSize * 8) / 2; 461 uint64_t psrc1_h = psrc1 >> halfSize; 462 uint64_t psrc1_l = psrc1 & mask(halfSize); 463 uint64_t psrc2_h = op2 >> halfSize; 464 uint64_t psrc2_l = op2 & mask(halfSize); 465 uint64_t result = 466 ((psrc1_l * psrc2_h) >> halfSize) + 467 ((psrc1_h * psrc2_l) >> halfSize) + 468 psrc1_h * psrc2_h; 469 DestReg = merge(DestReg, result, dataSize); |
548 ''') 549 defineMicroRegOp('Div1', ''' | 470 ''' 471 472 class Div1(FlagRegOp): 473 code = ''' |
550 int halfSize = (dataSize * 8) / 2; 551 IntReg quotient = (psrc1 / op2) & mask(halfSize); 552 IntReg remainder = (psrc1 % op2) & mask(halfSize); 553 IntReg result = quotient | (remainder << halfSize); 554 DestReg = merge(DestReg, result, dataSize); | 474 int halfSize = (dataSize * 8) / 2; 475 IntReg quotient = (psrc1 / op2) & mask(halfSize); 476 IntReg remainder = (psrc1 % op2) & mask(halfSize); 477 IntReg result = quotient | (remainder << halfSize); 478 DestReg = merge(DestReg, result, dataSize); |
555 ''') 556 defineMicroRegOp('Divq', ''' 557 DestReg = merge(DestReg, psrc1 / op2, dataSize); 558 ''') 559 defineMicroRegOp('Divr', ''' 560 DestReg = merge(DestReg, psrc1 % op2, dataSize); 561 ''') | 479 ''' |
562 | 480 |
563 # 564 # HACK HACK HACK HACK - Put psrc1 in here but make it inert to shut up gcc. 565 # 566 defineMicroRegOp('Mov', 567 'DestReg = merge(SrcReg1, psrc1 * 0 + op2, dataSize)', 568 elseCode='DestReg=DestReg;', cc=True) | 481 class Divq(FlagRegOp): 482 code = 'DestReg = merge(DestReg, psrc1 / op2, dataSize);' |
569 | 483 |
570 defineMicroRegOp('Movfp', 571 'FpDestReg = FpSrcReg2 + psrc1 * 0 + psrc2 * 0', 572 elseCode='FpDestReg=FpDestReg;', cc=True, doImm=False) | 484 class Divr(FlagRegOp): 485 code = 'DestReg = merge(DestReg, psrc1 % op2, dataSize);' |
573 | 486 |
487 class Mov(CondRegOp): 488 code = 'DestReg = merge(SrcReg1, op2, dataSize)' 489 else_code = 'DestReg=DestReg;' 490 491 class Movfp(CondRegOp): 492 code = 'FpDestReg = FpSrcReg2' 493 else_code = 'FpDestReg = FpDestReg;' 494 |
|
574 # Shift instructions | 495 # Shift instructions |
575 defineMicroRegOp('Sll', ''' | 496 497 class Sll(FlagRegOp): 498 code = ''' |
576 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 577 DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize); | 499 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 500 DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize); |
578 ''') 579 defineMicroRegOp('Srl', ''' | 501 ''' 502 503 class Srl(FlagRegOp): 504 code = ''' |
580 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 581 // Because what happens to the bits shift -in- on a right shift 582 // is not defined in the C/C++ standard, we have to mask them out 583 // to be sure they're zero. 584 uint64_t logicalMask = mask(dataSize * 8 - shiftAmt); 585 DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize); | 505 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 506 // Because what happens to the bits shift -in- on a right shift 507 // is not defined in the C/C++ standard, we have to mask them out 508 // to be sure they're zero. 509 uint64_t logicalMask = mask(dataSize * 8 - shiftAmt); 510 DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize); |
586 ''') 587 defineMicroRegOp('Sra', ''' | 511 ''' 512 513 class Sra(FlagRegOp): 514 code = ''' |
588 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 589 // Because what happens to the bits shift -in- on a right shift 590 // is not defined in the C/C++ standard, we have to sign extend 591 // them manually to be sure. 592 uint64_t arithMask = 593 -bits(psrc1, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt); 594 DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize); | 515 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 516 // Because what happens to the bits shift -in- on a right shift 517 // is not defined in the C/C++ standard, we have to sign extend 518 // them manually to be sure. 519 uint64_t arithMask = 520 -bits(psrc1, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt); 521 DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize); |
595 ''') 596 defineMicroRegOp('Ror', ''' | 522 ''' 523 524 class Ror(FlagRegOp): 525 code = ''' |
597 uint8_t shiftAmt = 598 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 599 if(shiftAmt) 600 { 601 uint64_t top = psrc1 << (dataSize * 8 - shiftAmt); 602 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt); 603 DestReg = merge(DestReg, top | bottom, dataSize); 604 } 605 else 606 DestReg = DestReg; | 526 uint8_t shiftAmt = 527 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 528 if(shiftAmt) 529 { 530 uint64_t top = psrc1 << (dataSize * 8 - shiftAmt); 531 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt); 532 DestReg = merge(DestReg, top | bottom, dataSize); 533 } 534 else 535 DestReg = DestReg; |
607 ''') 608 defineMicroRegOp('Rcr', ''' | 536 ''' 537 538 class Rcr(FlagRegOp): 539 code = ''' |
609 uint8_t shiftAmt = 610 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 611 if(shiftAmt) 612 { 613 CCFlagBits flags = ccFlagBits; 614 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt); 615 if(shiftAmt > 1) 616 top |= psrc1 << (dataSize * 8 - shiftAmt - 1); 617 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt); 618 DestReg = merge(DestReg, top | bottom, dataSize); 619 } 620 else 621 DestReg = DestReg; | 540 uint8_t shiftAmt = 541 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 542 if(shiftAmt) 543 { 544 CCFlagBits flags = ccFlagBits; 545 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt); 546 if(shiftAmt > 1) 547 top |= psrc1 << (dataSize * 8 - shiftAmt - 1); 548 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt); 549 DestReg = merge(DestReg, top | bottom, dataSize); 550 } 551 else 552 DestReg = DestReg; |
622 ''') 623 defineMicroRegOp('Rol', ''' | 553 ''' 554 555 class Rol(FlagRegOp): 556 code = ''' |
624 uint8_t shiftAmt = 625 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 626 if(shiftAmt) 627 { 628 uint64_t top = psrc1 << shiftAmt; 629 uint64_t bottom = 630 bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt); 631 DestReg = merge(DestReg, top | bottom, dataSize); 632 } 633 else 634 DestReg = DestReg; | 557 uint8_t shiftAmt = 558 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 559 if(shiftAmt) 560 { 561 uint64_t top = psrc1 << shiftAmt; 562 uint64_t bottom = 563 bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt); 564 DestReg = merge(DestReg, top | bottom, dataSize); 565 } 566 else 567 DestReg = DestReg; |
635 ''') 636 defineMicroRegOp('Rcl', ''' | 568 ''' 569 570 class Rcl(FlagRegOp): 571 code = ''' |
637 uint8_t shiftAmt = 638 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 639 if(shiftAmt) 640 { 641 CCFlagBits flags = ccFlagBits; 642 uint64_t top = psrc1 << shiftAmt; 643 uint64_t bottom = flags.CF << (shiftAmt - 1); 644 if(shiftAmt > 1) 645 bottom |= 646 bits(psrc1, dataSize * 8 - 1, 647 dataSize * 8 - shiftAmt + 1); 648 DestReg = merge(DestReg, top | bottom, dataSize); 649 } 650 else 651 DestReg = DestReg; | 572 uint8_t shiftAmt = 573 (op2 & ((dataSize == 8) ? mask(6) : mask(5))); 574 if(shiftAmt) 575 { 576 CCFlagBits flags = ccFlagBits; 577 uint64_t top = psrc1 << shiftAmt; 578 uint64_t bottom = flags.CF << (shiftAmt - 1); 579 if(shiftAmt > 1) 580 bottom |= 581 bits(psrc1, dataSize * 8 - 1, 582 dataSize * 8 - shiftAmt + 1); 583 DestReg = merge(DestReg, top | bottom, dataSize); 584 } 585 else 586 DestReg = DestReg; |
652 ''') | 587 ''' |
653 | 588 |
654 defineMicroRegOpWr('Wrip', 'RIP = psrc1 + op2', elseCode="RIP = RIP;") 655 defineMicroRegOpWr('Br', 'nuIP = psrc1 + op2;', elseCode='nuIP = nuIP;') 656 defineMicroRegOpWr('Wruflags', 'ccFlagBits = psrc1 ^ op2') | 589 class WrRegOp(RegOp): 590 abstract = True 591 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): 592 super(WrRegOp, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) |
657 | 593 |
658 defineMicroRegOpRd('Rdip', 'DestReg = RIP') 659 defineMicroRegOpRd('Ruflags', 'DestReg = ccFlagBits') 660 defineMicroRegOpRdImm('Ruflag', ''' | 594 class Wrip(WrRegOp, CondRegOp): 595 code = 'RIP = psrc1 + op2' 596 else_code="RIP = RIP;" 597 598 class Br(WrRegOp, CondRegOp): 599 code = 'nuIP = psrc1 + op2;' 600 else_code='nuIP = nuIP;' 601 602 class Wruflags(WrRegOp): 603 code = 'ccFlagBits = psrc1 ^ op2' 604 605 class RdRegOp(RegOp): 606 abstract = True 607 def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"): 608 super(RdRegOp, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize) 609 610 class Rdip(RdRegOp): 611 code = 'DestReg = RIP' 612 613 class Ruflags(RdRegOp): 614 code = 'DestReg = ccFlagBits' 615 616 class Ruflag(RegOp): 617 code = ''' |
661 int flag = bits(ccFlagBits, imm8 + 0*psrc1); 662 DestReg = merge(DestReg, flag, dataSize); 663 ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : 664 (ccFlagBits & ~EZFBit); | 618 int flag = bits(ccFlagBits, imm8 + 0*psrc1); 619 DestReg = merge(DestReg, flag, dataSize); 620 ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : 621 (ccFlagBits & ~EZFBit); |
665 ''') | 622 ''' 623 def __init__(self, dest, imm, flags=None, \ 624 dataSize="env.dataSize"): 625 super(Ruflag, self).__init__(dest, \ 626 "NUM_INTREGS", imm, flags, dataSize) |
666 | 627 |
667 defineMicroRegOpImm('Sext', ''' | 628 class Sext(RegOp): 629 code = ''' |
668 IntReg val = psrc1; 669 int sign_bit = bits(val, imm8-1, imm8-1); 670 uint64_t maskVal = mask(imm8); 671 val = sign_bit ? (val | ~maskVal) : (val & maskVal); 672 DestReg = merge(DestReg, val, dataSize); | 630 IntReg val = psrc1; 631 int sign_bit = bits(val, imm8-1, imm8-1); 632 uint64_t maskVal = mask(imm8); 633 val = sign_bit ? (val | ~maskVal) : (val & maskVal); 634 DestReg = merge(DestReg, val, dataSize); |
673 ''') | 635 ''' |
674 | 636 |
675 defineMicroRegOpImm('Zext', 'DestReg = bits(psrc1, imm8-1, 0);') | 637 class Zext(RegOp): 638 code = 'DestReg = bits(psrc1, imm8-1, 0);' |
676}}; | 639}}; |