regop.isa (4809:ee82bc15a483) regop.isa (4823:9bd81e315a34)
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

--- 314 unchanged lines hidden (view full) ---

323 "else_code" : elseCode})
324 header_output += MicroRegOpDeclare.subst(iop)
325 decoder_output += MicroRegOpConstructor.subst(iop)
326 exec_output += MicroRegOpExecute.subst(iop)
327
328
329 checkCCFlagBits = "checkCondition(ccFlagBits)"
330 genCCFlagBits = \
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

--- 314 unchanged lines hidden (view full) ---

323 "else_code" : elseCode})
324 header_output += MicroRegOpDeclare.subst(iop)
325 decoder_output += MicroRegOpConstructor.subst(iop)
326 exec_output += MicroRegOpExecute.subst(iop)
327
328
329 checkCCFlagBits = "checkCondition(ccFlagBits)"
330 genCCFlagBits = \
331 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, op2);"
331 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);"
332 genCCFlagBitsSub = \
332 genCCFlagBitsSub = \
333 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, ~op2, true);"
333 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);"
334 genCCFlagBitsLogic = '''
335 //Don't have genFlags handle the OF or CF bits
336 uint64_t mask = CFBit | OFBit;
334 genCCFlagBitsLogic = '''
335 //Don't have genFlags handle the OF or CF bits
336 uint64_t mask = CFBit | OFBit;
337 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, src1, op2);
337 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2);
338 //If a logic microop wants to set these, it wants to set them to 0.
339 ccFlagBits &= ~(CFBit & ext);
340 ccFlagBits &= ~(OFBit & ext);
341 '''
342
343 regPick = '''
338 //If a logic microop wants to set these, it wants to set them to 0.
339 ccFlagBits &= ~(CFBit & ext);
340 ccFlagBits &= ~(OFBit & ext);
341 '''
342
343 regPick = '''
344 IntReg src1 = pick(SrcReg1, 0, dataSize);
345 IntReg src2 = pick(SrcReg2, 1, dataSize);
344 IntReg psrc1 = pick(SrcReg1, 0, dataSize);
345 IntReg psrc2 = pick(SrcReg2, 1, dataSize);
346 '''
347 immPick = '''
346 '''
347 immPick = '''
348 IntReg src1 = pick(SrcReg1, 0, dataSize);
348 IntReg psrc1 = pick(SrcReg1, 0, dataSize);
349 '''
350
351
352 # This creates a python representations of a microop which are a cross
353 # product of reg/immediate and flag/no flag versions.
354 def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
355 cc=False, elseCode=";"):
356 Name = mnemonic
357 name = mnemonic.lower()
358
359 # Find op2 in each of the instruction definitions. Create two versions
360 # of the code, one with an integer operand, and one with an immediate
361 # operand.
362 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
349 '''
350
351
352 # This creates a python representations of a microop which are a cross
353 # product of reg/immediate and flag/no flag versions.
354 def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
355 cc=False, elseCode=";"):
356 Name = mnemonic
357 name = mnemonic.lower()
358
359 # Find op2 in each of the instruction definitions. Create two versions
360 # of the code, one with an integer operand, and one with an immediate
361 # operand.
362 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
363 regCode = regPick + matcher.sub("src2", code)
363 regCode = regPick + matcher.sub("psrc2", code)
364 immCode = immPick + matcher.sub("imm8", code)
365
366 if not cc:
367 condCode = "true"
368 else:
369 flagCode = ""
370 condCode = checkCCFlagBits
371
364 immCode = immPick + matcher.sub("imm8", code)
365
366 if not cc:
367 condCode = "true"
368 else:
369 flagCode = ""
370 condCode = checkCCFlagBits
371
372 regFlagCode = matcher.sub("src2", flagCode)
372 regFlagCode = matcher.sub("psrc2", flagCode)
373 immFlagCode = matcher.sub("imm8", flagCode)
374
375 class RegOpChild(RegOp):
376 mnemonic = name
377 className = Name
378 def __init__(self, dest, src1, src2, \
379 flags=None, dataSize="env.dataSize"):
380 super(RegOpChild, self).__init__(dest, src1, src2, \

--- 25 unchanged lines hidden (view full) ---

406 def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
407 Name = mnemonic
408 name = mnemonic.lower()
409
410 # Find op2 in each of the instruction definitions. Create two versions
411 # of the code, one with an integer operand, and one with an immediate
412 # operand.
413 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
373 immFlagCode = matcher.sub("imm8", flagCode)
374
375 class RegOpChild(RegOp):
376 mnemonic = name
377 className = Name
378 def __init__(self, dest, src1, src2, \
379 flags=None, dataSize="env.dataSize"):
380 super(RegOpChild, self).__init__(dest, src1, src2, \

--- 25 unchanged lines hidden (view full) ---

406 def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
407 Name = mnemonic
408 name = mnemonic.lower()
409
410 # Find op2 in each of the instruction definitions. Create two versions
411 # of the code, one with an integer operand, and one with an immediate
412 # operand.
413 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
414 regCode = regPick + matcher.sub("src2", code)
414 regCode = regPick + matcher.sub("psrc2", code)
415 immCode = immPick + matcher.sub("imm8", code)
416
417 class RegOpChild(RegOp):
418 mnemonic = name
419 className = Name
420 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
421 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
422

--- 40 unchanged lines hidden (view full) ---

463 super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize)
464 self.className = Name
465 self.mnemonic = name
466
467 microopClasses[name] = RegOpChild
468
469 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
470
415 immCode = immPick + matcher.sub("imm8", code)
416
417 class RegOpChild(RegOp):
418 mnemonic = name
419 className = Name
420 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
421 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
422

--- 40 unchanged lines hidden (view full) ---

463 super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize)
464 self.className = Name
465 self.mnemonic = name
466
467 microopClasses[name] = RegOpChild
468
469 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
470
471 defineMicroRegOp('Add', 'DestReg = merge(DestReg, src1 + op2, dataSize)')
472 defineMicroRegOp('Or', '''
473 DPRINTF(X86, "src1 = %#x\\n", src1);
474 DPRINTF(X86, "op2 = %#x\\n", op2);
475 DestReg = merge(DestReg, src1 | op2, dataSize);
476 ''',
471 defineMicroRegOp('Add', 'DestReg = merge(DestReg, psrc1 + op2, dataSize)')
472 defineMicroRegOp('Or', 'DestReg = merge(DestReg, psrc1 | op2, dataSize);',
477 flagCode = genCCFlagBitsLogic)
478 defineMicroRegOp('Adc', '''
479 CCFlagBits flags = ccFlagBits;
473 flagCode = genCCFlagBitsLogic)
474 defineMicroRegOp('Adc', '''
475 CCFlagBits flags = ccFlagBits;
480 DestReg = merge(DestReg, src1 + op2 + flags.CF, dataSize);
476 DestReg = merge(DestReg, psrc1 + op2 + flags.CF, dataSize);
481 ''')
482 defineMicroRegOp('Sbb', '''
483 CCFlagBits flags = ccFlagBits;
477 ''')
478 defineMicroRegOp('Sbb', '''
479 CCFlagBits flags = ccFlagBits;
484 DestReg = merge(DestReg, src1 - op2 - flags.CF, dataSize);
480 DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize);
485 ''', flagCode = genCCFlagBitsSub)
486 defineMicroRegOp('And', \
481 ''', flagCode = genCCFlagBitsSub)
482 defineMicroRegOp('And', \
487 'DestReg = merge(DestReg, src1 & op2, dataSize)', \
483 'DestReg = merge(DestReg, psrc1 & op2, dataSize)', \
488 flagCode = genCCFlagBitsLogic)
489 defineMicroRegOp('Sub', \
484 flagCode = genCCFlagBitsLogic)
485 defineMicroRegOp('Sub', \
490 'DestReg = merge(DestReg, src1 - op2, dataSize)', \
486 'DestReg = merge(DestReg, psrc1 - op2, dataSize)', \
491 flagCode = genCCFlagBitsSub)
492 defineMicroRegOp('Xor', \
487 flagCode = genCCFlagBitsSub)
488 defineMicroRegOp('Xor', \
493 'DestReg = merge(DestReg, src1 ^ op2, dataSize)', \
489 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)', \
494 flagCode = genCCFlagBitsLogic)
495 defineMicroRegOp('Mul1s', '''
496 int signPos = (dataSize * 8) / 2 - 1;
490 flagCode = genCCFlagBitsLogic)
491 defineMicroRegOp('Mul1s', '''
492 int signPos = (dataSize * 8) / 2 - 1;
497 IntReg srcVal1 = src1 | (-bits(src1, signPos) << signPos);
498 IntReg srcVal2 = op2 | (-bits(src1, signPos) << signPos);
493 IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos);
494 IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos);
499 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
500 ''')
501 defineMicroRegOp('Mul1u', '''
502 int halfSize = (dataSize * 8) / 2;
495 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
496 ''')
497 defineMicroRegOp('Mul1u', '''
498 int halfSize = (dataSize * 8) / 2;
503 IntReg srcVal1 = src1 & mask(halfSize);
499 IntReg srcVal1 = psrc1 & mask(halfSize);
504 IntReg srcVal2 = op2 & mask(halfSize);
505 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
506 ''')
507 defineMicroRegOp('Mulel', \
500 IntReg srcVal2 = op2 & mask(halfSize);
501 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
502 ''')
503 defineMicroRegOp('Mulel', \
508 'DestReg = merge(DestReg, src1 * op2, dataSize)')
504 'DestReg = merge(DestReg, psrc1 * op2, dataSize)')
509 defineMicroRegOp('Muleh', '''
510 int halfSize = (dataSize * 8) / 2;
505 defineMicroRegOp('Muleh', '''
506 int halfSize = (dataSize * 8) / 2;
511 uint64_t src1_h = src1 >> halfSize;
512 uint64_t src1_l = src1 & mask(halfSize);
513 uint64_t src2_h = op2 >> halfSize;
514 uint64_t src2_l = op2 & mask(halfSize);
507 uint64_t psrc1_h = psrc1 >> halfSize;
508 uint64_t psrc1_l = psrc1 & mask(halfSize);
509 uint64_t psrc2_h = op2 >> halfSize;
510 uint64_t psrc2_l = op2 & mask(halfSize);
515 uint64_t result =
511 uint64_t result =
516 ((src1_l * src2_h) >> halfSize) +
517 ((src1_h * src2_l) >> halfSize) +
518 src1_h * src2_h;
512 ((psrc1_l * psrc2_h) >> halfSize) +
513 ((psrc1_h * psrc2_l) >> halfSize) +
514 psrc1_h * psrc2_h;
519 DestReg = merge(DestReg, result, dataSize);
520 ''')
515 DestReg = merge(DestReg, result, dataSize);
516 ''')
517 defineMicroRegOp('Div1', '''
518 int halfSize = (dataSize * 8) / 2;
519 IntReg quotient = (psrc1 / op2) & mask(halfSize);
520 IntReg remainder = (psrc1 % op2) & mask(halfSize);
521 IntReg result = quotient | (remainder << halfSize);
522 DestReg = merge(DestReg, result, dataSize);
523 ''')
524 defineMicroRegOp('Divq', '''
525 DestReg = merge(DestReg, psrc1 / op2, dataSize);
526 ''')
527 defineMicroRegOp('Divr', '''
528 DestReg = merge(DestReg, psrc1 % op2, dataSize);
529 ''')
530
521 #
531 #
522 # HACK HACK HACK HACK - Put src1 in here but make it inert to shut up gcc.
532 # HACK HACK HACK HACK - Put psrc1 in here but make it inert to shut up gcc.
523 #
533 #
524 defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, src1 * 0 + op2, dataSize)',
534 defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, psrc1 * 0 + op2, dataSize)',
525 elseCode='DestReg=DestReg;', cc=True)
526
527 # Shift instructions
528 defineMicroRegOp('Sll', '''
529 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
535 elseCode='DestReg=DestReg;', cc=True)
536
537 # Shift instructions
538 defineMicroRegOp('Sll', '''
539 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
530 DestReg = merge(DestReg, src1 << shiftAmt, dataSize);
540 DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize);
531 ''')
532 defineMicroRegOp('Srl', '''
533 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
534 // Because what happens to the bits shift -in- on a right shift
535 // is not defined in the C/C++ standard, we have to mask them out
536 // to be sure they're zero.
537 uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
541 ''')
542 defineMicroRegOp('Srl', '''
543 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
544 // Because what happens to the bits shift -in- on a right shift
545 // is not defined in the C/C++ standard, we have to mask them out
546 // to be sure they're zero.
547 uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
538 DestReg = merge(DestReg, (src1 >> shiftAmt) & logicalMask, dataSize);
548 DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize);
539 ''')
540 defineMicroRegOp('Sra', '''
541 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
542 // Because what happens to the bits shift -in- on a right shift
543 // is not defined in the C/C++ standard, we have to sign extend
544 // them manually to be sure.
545 uint64_t arithMask =
546 -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
549 ''')
550 defineMicroRegOp('Sra', '''
551 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
552 // Because what happens to the bits shift -in- on a right shift
553 // is not defined in the C/C++ standard, we have to sign extend
554 // them manually to be sure.
555 uint64_t arithMask =
556 -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
547 DestReg = merge(DestReg, (src1 >> shiftAmt) | arithMask, dataSize);
557 DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize);
548 ''')
549 defineMicroRegOp('Ror', '''
550 uint8_t shiftAmt =
551 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
552 if(shiftAmt)
553 {
558 ''')
559 defineMicroRegOp('Ror', '''
560 uint8_t shiftAmt =
561 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
562 if(shiftAmt)
563 {
554 uint64_t top = src1 << (dataSize * 8 - shiftAmt);
555 uint64_t bottom = bits(src1, dataSize * 8, shiftAmt);
564 uint64_t top = psrc1 << (dataSize * 8 - shiftAmt);
565 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
556 DestReg = merge(DestReg, top | bottom, dataSize);
557 }
558 else
559 DestReg = DestReg;
560 ''')
561 defineMicroRegOp('Rcr', '''
562 uint8_t shiftAmt =
563 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
564 if(shiftAmt)
565 {
566 CCFlagBits flags = ccFlagBits;
567 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
568 if(shiftAmt > 1)
566 DestReg = merge(DestReg, top | bottom, dataSize);
567 }
568 else
569 DestReg = DestReg;
570 ''')
571 defineMicroRegOp('Rcr', '''
572 uint8_t shiftAmt =
573 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
574 if(shiftAmt)
575 {
576 CCFlagBits flags = ccFlagBits;
577 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
578 if(shiftAmt > 1)
569 top |= src1 << (dataSize * 8 - shiftAmt - 1);
570 uint64_t bottom = bits(src1, dataSize * 8, shiftAmt);
579 top |= psrc1 << (dataSize * 8 - shiftAmt - 1);
580 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
571 DestReg = merge(DestReg, top | bottom, dataSize);
572 }
573 else
574 DestReg = DestReg;
575 ''')
576 defineMicroRegOp('Rol', '''
577 uint8_t shiftAmt =
578 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
579 if(shiftAmt)
580 {
581 DestReg = merge(DestReg, top | bottom, dataSize);
582 }
583 else
584 DestReg = DestReg;
585 ''')
586 defineMicroRegOp('Rol', '''
587 uint8_t shiftAmt =
588 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
589 if(shiftAmt)
590 {
581 uint64_t top = src1 << shiftAmt;
591 uint64_t top = psrc1 << shiftAmt;
582 uint64_t bottom =
592 uint64_t bottom =
583 bits(src1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
593 bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
584 DestReg = merge(DestReg, top | bottom, dataSize);
585 }
586 else
587 DestReg = DestReg;
588 ''')
589 defineMicroRegOp('Rcl', '''
590 uint8_t shiftAmt =
591 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
592 if(shiftAmt)
593 {
594 CCFlagBits flags = ccFlagBits;
594 DestReg = merge(DestReg, top | bottom, dataSize);
595 }
596 else
597 DestReg = DestReg;
598 ''')
599 defineMicroRegOp('Rcl', '''
600 uint8_t shiftAmt =
601 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
602 if(shiftAmt)
603 {
604 CCFlagBits flags = ccFlagBits;
595 uint64_t top = src1 << shiftAmt;
605 uint64_t top = psrc1 << shiftAmt;
596 uint64_t bottom = flags.CF << (shiftAmt - 1);
597 if(shiftAmt > 1)
598 bottom |=
606 uint64_t bottom = flags.CF << (shiftAmt - 1);
607 if(shiftAmt > 1)
608 bottom |=
599 bits(src1, dataSize * 8 - 1,
609 bits(psrc1, dataSize * 8 - 1,
600 dataSize * 8 - shiftAmt + 1);
601 DestReg = merge(DestReg, top | bottom, dataSize);
602 }
603 else
604 DestReg = DestReg;
605 ''')
606
610 dataSize * 8 - shiftAmt + 1);
611 DestReg = merge(DestReg, top | bottom, dataSize);
612 }
613 else
614 DestReg = DestReg;
615 ''')
616
607 defineMicroRegOpWr('Wrip', 'RIP = src1 + op2', elseCode="RIP = RIP;")
617 defineMicroRegOpWr('Wrip', 'RIP = psrc1 + op2', elseCode="RIP = RIP;")
608
609 defineMicroRegOpRd('Rdip', 'DestReg = RIP')
610
611 defineMicroRegOpImm('Sext', '''
618
619 defineMicroRegOpRd('Rdip', 'DestReg = RIP')
620
621 defineMicroRegOpImm('Sext', '''
612 IntReg val = src1;
622 IntReg val = psrc1;
613 int sign_bit = bits(val, imm8-1, imm8-1);
614 val = sign_bit ? (val | ~mask(imm8)) : val;
615 DestReg = merge(DestReg, val, dataSize);''')
616
623 int sign_bit = bits(val, imm8-1, imm8-1);
624 val = sign_bit ? (val | ~mask(imm8)) : val;
625 DestReg = merge(DestReg, val, dataSize);''')
626
617 defineMicroRegOpImm('Zext', 'DestReg = bits(src1, imm8-1, 0);')
627 defineMicroRegOpImm('Zext', 'DestReg = bits(psrc1, imm8-1, 0);')
618}};
628}};