regop.isa (4798:85351424da98) regop.isa (4809:ee82bc15a483)
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

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

60//////////////////////////////////////////////////////////////////////////
61
62def template MicroRegOpExecute {{
63 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
64 Trace::InstRecord *traceData) const
65 {
66 Fault fault = NoFault;
67
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

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

60//////////////////////////////////////////////////////////////////////////
61
62def template MicroRegOpExecute {{
63 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
64 Trace::InstRecord *traceData) const
65 {
66 Fault fault = NoFault;
67
68 DPRINTF(X86, "The data size is %d\n", dataSize);
68 %(op_decl)s;
69 %(op_rd)s;
70
71 if(%(cond_check)s)
72 {
73 %(code)s;
74 %(flag_code)s;
75 }

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

322 "else_code" : elseCode})
323 header_output += MicroRegOpDeclare.subst(iop)
324 decoder_output += MicroRegOpConstructor.subst(iop)
325 exec_output += MicroRegOpExecute.subst(iop)
326
327
328 checkCCFlagBits = "checkCondition(ccFlagBits)"
329 genCCFlagBits = \
69 %(op_decl)s;
70 %(op_rd)s;
71
72 if(%(cond_check)s)
73 {
74 %(code)s;
75 %(flag_code)s;
76 }

--- 246 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 = \
330 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, op2);"
331 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, op2);"
331 genCCFlagBitsSub = \
332 genCCFlagBitsSub = \
332 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, ~op2, true);"
333 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, src1, ~op2, true);"
333 genCCFlagBitsLogic = '''
334 //Don't have genFlags handle the OF or CF bits
335 uint64_t mask = CFBit | OFBit;
334 genCCFlagBitsLogic = '''
335 //Don't have genFlags handle the OF or CF bits
336 uint64_t mask = CFBit | OFBit;
336 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, SrcReg1, op2);
337 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, src1, op2);
337 //If a logic microop wants to set these, it wants to set them to 0.
338 ccFlagBits &= ~(CFBit & ext);
339 ccFlagBits &= ~(OFBit & ext);
340 '''
341
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);
346 '''
347 immPick = '''
348 IntReg src1 = pick(SrcReg1, 0, dataSize);
349 '''
342
350
351
343 # This creates a python representations of a microop which are a cross
344 # product of reg/immediate and flag/no flag versions.
345 def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
346 cc=False, elseCode=";"):
347 Name = mnemonic
348 name = mnemonic.lower()
349
350 # Find op2 in each of the instruction definitions. Create two versions
351 # of the code, one with an integer operand, and one with an immediate
352 # operand.
353 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
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+)?")
354 regCode = matcher.sub("SrcReg2", code)
355 immCode = matcher.sub("imm8", code)
363 regCode = regPick + matcher.sub("src2", code)
364 immCode = immPick + matcher.sub("imm8", code)
356
357 if not cc:
358 condCode = "true"
359 else:
360 flagCode = ""
361 condCode = checkCCFlagBits
362
365
366 if not cc:
367 condCode = "true"
368 else:
369 flagCode = ""
370 condCode = checkCCFlagBits
371
363 regFlagCode = matcher.sub("SrcReg2", flagCode)
372 regFlagCode = matcher.sub("src2", flagCode)
364 immFlagCode = matcher.sub("imm8", flagCode)
365
366 class RegOpChild(RegOp):
367 mnemonic = name
368 className = Name
369 def __init__(self, dest, src1, src2, \
370 flags=None, dataSize="env.dataSize"):
371 super(RegOpChild, self).__init__(dest, src1, src2, \
372 flags, dataSize)
373
374 microopClasses[name] = RegOpChild
375
376 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
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, \
381 flags, dataSize)
382
383 microopClasses[name] = RegOpChild
384
385 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
377 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
378 flagCode=regFlagCode, condCheck=condCode, elseCode=elseCode);
386 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp",
387 regCode, flagCode=regFlagCode,
388 condCheck=condCode, elseCode=elseCode);
379
380 class RegOpChildImm(RegOpImm):
381 mnemonic = name + 'i'
382 className = Name + 'Imm'
383 def __init__(self, dest, src1, src2, \
384 flags=None, dataSize="env.dataSize"):
385 super(RegOpChildImm, self).__init__(dest, src1, src2, \
386 flags, dataSize)
387
388 microopClasses[name + 'i'] = RegOpChildImm
389
390 setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
389
390 class RegOpChildImm(RegOpImm):
391 mnemonic = name + 'i'
392 className = Name + 'Imm'
393 def __init__(self, dest, src1, src2, \
394 flags=None, dataSize="env.dataSize"):
395 super(RegOpChildImm, self).__init__(dest, src1, src2, \
396 flags, dataSize)
397
398 microopClasses[name + 'i'] = RegOpChildImm
399
400 setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode);
391 setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
392 flagCode=immFlagCode, condCheck=condCode, elseCode=elseCode);
401 setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm",
402 immCode, flagCode=immFlagCode,
403 condCheck=condCode, elseCode=elseCode);
393
394 # This has it's own function because Wr ops have implicit destinations
395 def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
396 Name = mnemonic
397 name = mnemonic.lower()
398
399 # Find op2 in each of the instruction definitions. Create two versions
400 # of the code, one with an integer operand, and one with an immediate
401 # operand.
402 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
404
405 # This has it's own function because Wr ops have implicit destinations
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+)?")
403 regCode = matcher.sub("SrcReg2", code)
404 immCode = matcher.sub("imm8", code)
414 regCode = regPick + matcher.sub("src2", code)
415 immCode = immPick + matcher.sub("imm8", code)
405
406 class RegOpChild(RegOp):
407 mnemonic = name
408 className = Name
409 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
410 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
411
412 microopClasses[name] = RegOpChild

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

440
441 microopClasses[name] = RegOpChild
442
443 setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
444
445 def defineMicroRegOpImm(mnemonic, code):
446 Name = mnemonic
447 name = mnemonic.lower()
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
423 microopClasses[name] = RegOpChild

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

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