- # A function which builds the C++ classes that implement the microops
- def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";", imm=False):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
-
- iop = InstObjParams(name, Name, base,
- {"code" : code,
- "flag_code" : flagCode,
- "cond_check" : condCheck,
- "else_code" : elseCode})
- if imm:
- header_output += MicroRegOpImmDeclare.subst(iop)
- decoder_output += MicroRegOpImmConstructor.subst(iop)
- exec_output += MicroRegOpImmExecute.subst(iop)
- else:
- header_output += MicroRegOpDeclare.subst(iop)
- decoder_output += MicroRegOpConstructor.subst(iop)
- exec_output += MicroRegOpExecute.subst(iop)
-
-
- checkCCFlagBits = "checkCondition(ccFlagBits)"
- genCCFlagBits = \
- "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);"
- genCCFlagBitsSub = \
- "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);"
- genCCFlagBitsLogic = '''
- //Don't have genFlags handle the OF or CF bits
- uint64_t mask = CFBit | OFBit;
- ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2);
- //If a logic microop wants to set these, it wants to set them to 0.
- ccFlagBits &= ~(CFBit & ext);
- ccFlagBits &= ~(OFBit & ext);
- '''
-
- regPick = '''
- IntReg psrc1 = pick(SrcReg1, 0, dataSize);
- IntReg psrc2 = pick(SrcReg2, 1, dataSize);
- '''
- immPick = '''
- IntReg psrc1 = pick(SrcReg1, 0, dataSize);
- '''
-
-
- # This creates a python representations of a microop which are a cross
- # product of reg/immediate and flag/no flag versions.
- def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
- cc=False, doImm=True, elseCode=";"):
- Name = mnemonic
- name = mnemonic.lower()
-
- # Find op2 in each of the instruction definitions. Create two versions
- # of the code, one with an integer operand, and one with an immediate
- # operand.
- matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
- regCode = regPick + matcher.sub("psrc2", code)
- immCode = immPick + matcher.sub("imm8", code)
-
- if not cc:
- condCode = "true"
- else:
- flagCode = ""
- condCode = checkCCFlagBits
-
- regFlagCode = matcher.sub("psrc2", flagCode)
- immFlagCode = matcher.sub("imm8", flagCode)
-
- class RegOpChild(RegOp):
- mnemonic = name
- className = Name
- def __init__(self, dest, src1, src2, \
- flags=None, dataSize="env.dataSize"):
- super(RegOpChild, self).__init__(dest, src1, src2, \
- flags, dataSize)
-
- microopClasses[name] = RegOpChild
-
- setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
- setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp",
- regCode, flagCode=regFlagCode,
- condCheck=condCode, elseCode=elseCode);
-
- if doImm:
- class RegOpChildImm(RegOpImm):
- mnemonic = name + 'i'
- className = Name + 'Imm'
- def __init__(self, dest, src1, src2, \
- flags=None, dataSize="env.dataSize"):
- super(RegOpChildImm, self).__init__(dest, src1, src2, \
- flags, dataSize)
-
- microopClasses[name + 'i'] = RegOpChildImm
-
- setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \
- immCode, imm=True);
- setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm",
- immCode, flagCode=immFlagCode,
- condCheck=condCode, elseCode=elseCode, imm=True);
-
- # This has it's own function because Wr ops have implicit destinations
- def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
- Name = mnemonic
- name = mnemonic.lower()
-
- # Find op2 in each of the instruction definitions. Create two versions
- # of the code, one with an integer operand, and one with an immediate
- # operand.
- matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
- regCode = regPick + matcher.sub("psrc2", code)
- immCode = immPick + matcher.sub("imm8", code)
-
- class RegOpChild(RegOp):
- mnemonic = name
- className = Name
- def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
- super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
-
- microopClasses[name] = RegOpChild
-
- setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
- setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
- condCheck = checkCCFlagBits, elseCode = elseCode);
-
- class RegOpChildImm(RegOpImm):
- mnemonic = name + 'i'
- className = Name + 'Imm'
- def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
- super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
-
- microopClasses[name + 'i'] = RegOpChildImm
-
- setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", \
- immCode, imm=True);
- setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", \
- immCode, condCheck = checkCCFlagBits, elseCode = elseCode, \
- imm=True);
-
- # This has it's own function because Rd ops don't always have two parameters
- def defineMicroRegOpRd(mnemonic, code):
- Name = mnemonic
- name = mnemonic.lower()
-
- class RegOpChild(RegOp):
- className = Name
- mnemonic = name
- def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
- super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
-
- microopClasses[name] = RegOpChild
-
- setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
-
- def defineMicroRegOpImm(mnemonic, code, flagCode=""):
- Name = mnemonic
- name = mnemonic.lower()
- code = immPick + code
-
- class RegOpChild(RegOpImm):
- className = Name
- mnemonic = name
- def __init__(self, dest, src1, src2, \
- flags=None, dataSize="env.dataSize"):
- super(RegOpChild, self).__init__(dest, \
- src1, src2, flags, dataSize)
-
- microopClasses[name] = RegOpChild
-
- setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, imm=True);
- setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOpImm", \
- code, flagCode=flagCode, imm=True);
-
- def defineMicroRegOpRdImm(mnemonic, code, flagCode=""):
- Name = mnemonic
- name = mnemonic.lower()
- code = immPick + code
-
- class RegOpChildRdImm(RegOpImm):
- className = Name
- mnemonic = name
- def __init__(self, dest, imm, flags=None, \
- dataSize="env.dataSize"):
- super(RegOpChildRdImm, self).__init__(dest, \
- "NUM_INTREGS", imm, flags, dataSize)
-
- microopClasses[name] = RegOpChildRdImm
-
- setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, imm=True);
- setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOpImm", \
- code, flagCode=flagCode, imm=True);
-
- defineMicroRegOp('Add', 'DestReg = merge(DestReg, psrc1 + op2, dataSize)')
- defineMicroRegOp('Or', 'DestReg = merge(DestReg, psrc1 | op2, dataSize);',
- flagCode = genCCFlagBitsLogic)
- defineMicroRegOp('Adc', '''