summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa/microops/regop.isa
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-07-22 10:40:45 -0400
committerSteve Reinhardt <stever@eecs.umich.edu>2007-07-22 10:40:45 -0400
commit03730edc45e2e00bdec58dabc84e94c632634a1a (patch)
treeaffdbffcb174a9cfc0de933f3c240ae5f2813292 /src/arch/x86/isa/microops/regop.isa
parent658eeee50715d9fd334ae3fd3e0e21b6db6de0c4 (diff)
parent2cd454d102b5da828b0fbf4b66ef1a24875e69f6 (diff)
downloadgem5-03730edc45e2e00bdec58dabc84e94c632634a1a.tar.xz
Merge Gabe's changes with mine.
--HG-- extra : convert_revision : f50ed42e7acb3f11e610fd6976eaa8df0c6ba2ab
Diffstat (limited to 'src/arch/x86/isa/microops/regop.isa')
-rw-r--r--src/arch/x86/isa/microops/regop.isa419
1 files changed, 249 insertions, 170 deletions
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 65b75fab8..dbbe11c90 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -59,100 +59,6 @@
//
//////////////////////////////////////////////////////////////////////////
-output header {{
- /**
- * Base classes for RegOps which provides a generateDisassembly method.
- */
- class RegOp : public X86MicroopBase
- {
- protected:
- const RegIndex src1;
- const RegIndex src2;
- const RegIndex dest;
- const bool setStatus;
- const uint8_t dataSize;
- const uint8_t ext;
-
- // Constructor
- RegOp(ExtMachInst _machInst,
- const char *mnem, const char *_instMnem,
- bool isMicro, bool isDelayed,
- bool isFirst, bool isLast,
- RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem,
- isMicro, isDelayed, isFirst, isLast,
- __opClass),
- src1(_src1), src2(_src2), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-
- class RegOpImm : public X86MicroopBase
- {
- protected:
- const RegIndex src1;
- const uint8_t imm8;
- const RegIndex dest;
- const bool setStatus;
- const uint8_t dataSize;
- const uint8_t ext;
-
- // Constructor
- RegOpImm(ExtMachInst _machInst,
- const char * mnem, const char *_instMnem,
- bool isMicro, bool isDelayed,
- bool isFirst, bool isLast,
- RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext,
- OpClass __opClass) :
- X86MicroopBase(_machInst, mnem, _instMnem,
- isMicro, isDelayed, isFirst, isLast,
- __opClass),
- src1(_src1), imm8(_imm8), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
- };
-}};
-
-output decoder {{
- std::string RegOp::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest);
- response << ", ";
- printReg(response, src1);
- response << ", ";
- printReg(response, src2);
- return response.str();
- }
-
- std::string RegOpImm::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream response;
-
- printMnemonic(response, instMnem, mnemonic);
- printReg(response, dest);
- response << ", ";
- printReg(response, src1);
- ccprintf(response, ", %#x", imm8);
- return response.str();
- }
-}};
-
def template MicroRegOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
@@ -161,8 +67,16 @@ def template MicroRegOpExecute {{
%(op_decl)s;
%(op_rd)s;
- %(code)s;
- %(flag_code)s;
+
+ if(%(cond_check)s)
+ {
+ %(code)s;
+ %(flag_code)s;
+ }
+ else
+ {
+ %(else_code)s;
+ }
//Write the resulting state to the execution context
if(fault == NoFault)
@@ -181,8 +95,16 @@ def template MicroRegOpImmExecute {{
%(op_decl)s;
%(op_rd)s;
- %(code)s;
- %(flag_code)s;
+
+ if(%(cond_check)s)
+ {
+ %(code)s;
+ %(flag_code)s;
+ }
+ else
+ {
+ %(else_code)s;
+ }
//Write the resulting state to the execution context
if(fault == NoFault)
@@ -204,12 +126,12 @@ def template MicroRegOpDeclare {{
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s
};
@@ -227,12 +149,12 @@ def template MicroRegOpImmDeclare {{
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(class_name)sImm(ExtMachInst _machInst,
const char * instMnem,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext);
+ uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s
};
@@ -248,10 +170,10 @@ def template MicroRegOpConstructor {{
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
- _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+ _src1, _src2, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -261,10 +183,10 @@ def template MicroRegOpConstructor {{
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
- _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+ _src1, _src2, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -281,10 +203,10 @@ def template MicroRegOpImmConstructor {{
inline %(class_name)sImm::%(class_name)sImm(
ExtMachInst machInst, const char * instMnem,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
- _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+ _src1, _imm8, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -294,10 +216,10 @@ def template MicroRegOpImmConstructor {{
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
- bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
+ uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
- _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+ _src1, _imm8, _dest, _dataSize, _ext,
%(op_class)s)
{
buildMe();
@@ -305,46 +227,74 @@ def template MicroRegOpImmConstructor {{
}};
let {{
+ class X86MicroMeta(type):
+ def __new__(mcls, name, bases, dict):
+ abstract = False
+ if "abstract" in dict:
+ abstract = dict['abstract']
+ del dict['abstract']
+
+ cls = type.__new__(mcls, name, bases, dict)
+ if not abstract:
+ allClasses[name] = cls
+ return cls
+
+ class XXX86Microop(object):
+ __metaclass__ = X86MicroMeta
+ abstract = True
+
class RegOp(X86Microop):
- def __init__(self, dest, src1, src2, setStatus):
+ abstract = True
+ def __init__(self, dest, src1, src2, flags, dataSize):
self.dest = dest
self.src1 = src1
self.src2 = src2
- self.setStatus = setStatus
- self.dataSize = "env.dataSize"
- self.ext = 0
+ self.flags = flags
+ self.dataSize = dataSize
+ if flags is None:
+ self.ext = 0
+ else:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.ext = " | ".join(flags)
+ self.className += "Flags"
def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, mnemonic
%(flags)s, %(src1)s, %(src2)s, %(dest)s,
- %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
+ %(dataSize)s, %(ext)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "src2" : self.src2,
"dest" : self.dest,
- "setStatus" : self.cppBool(self.setStatus),
"dataSize" : self.dataSize,
"ext" : self.ext}
return allocator
class RegOpImm(X86Microop):
- def __init__(self, dest, src1, imm8, setStatus):
+ abstract = True
+ def __init__(self, dest, src1, imm8, flags, dataSize):
self.dest = dest
self.src1 = src1
self.imm8 = imm8
- self.setStatus = setStatus
- self.dataSize = "env.dataSize"
- self.ext = 0
+ self.flags = flags
+ self.dataSize = dataSize
+ if flags is None:
+ self.ext = 0
+ else:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception, "flags must be a list or tuple of flags"
+ self.ext = " | ".join(flags)
+ self.className += "Flags"
def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, mnemonic
%(flags)s, %(src1)s, %(imm8)s, %(dest)s,
- %(setStatus)s, %(dataSize)s, %(ext)s)''' % {
+ %(dataSize)s, %(ext)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "imm8" : self.imm8,
"dest" : self.dest,
- "setStatus" : self.cppBool(self.setStatus),
"dataSize" : self.dataSize,
"ext" : self.ext}
return allocator
@@ -358,7 +308,8 @@ let {{
decoder_output = ""
exec_output = ""
- def setUpMicroRegOp(name, Name, base, code, child, flagCode):
+ # A function which builds the C++ classes that implement the microops
+ def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";"):
global header_output
global decoder_output
global exec_output
@@ -366,14 +317,21 @@ let {{
iop = InstObjParams(name, Name, base,
{"code" : code,
- "flag_code" : flagCode})
+ "flag_code" : flagCode,
+ "cond_check" : condCheck,
+ "else_code" : elseCode})
header_output += MicroRegOpDeclare.subst(iop)
decoder_output += MicroRegOpConstructor.subst(iop)
exec_output += MicroRegOpExecute.subst(iop)
- microopClasses[name] = child
- def defineMicroRegOp(mnemonic, code, flagCode):
+ checkCCFlagBits = "checkCondition(ccFlagBits)"
+ genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
+
+
+ # 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, subtract = False, cc=False, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@@ -384,36 +342,47 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
- # Build the all register version of this micro op
+ if subtract:
+ secondSrc = "-op2, true"
+ else:
+ secondSrc = "op2"
+
+ if not cc:
+ flagCode = genCCFlagBits % secondSrc
+ condCode = "true"
+ else:
+ flagCode = ""
+ condCode = checkCCFlagBits
+
+ regFlagCode = matcher.sub("SrcReg2", flagCode)
+ immFlagCode = matcher.sub("imm8", flagCode)
+
class RegOpChild(RegOp):
- def __init__(self, dest, src1, src2, setStatus=False):
- super(RegOpChild, self).__init__(dest, src1, src2, setStatus)
- self.className = Name
- self.mnemonic = name
+ 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, "RegOp", regCode, RegOpChild, flagCode);
+ setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
+ setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
+ flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode);
- # Build the immediate version of this micro op
class RegOpChildImm(RegOpImm):
- def __init__(self, dest, src1, src2, setStatus=False):
- super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus)
- self.className = Name + "Imm"
- self.mnemonic = name + "i"
-
- setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode);
-
- defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF
- defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "")
- defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF
- defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF
- defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "")
- defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF
- defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "")
- defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg
- defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "")
+ 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);
+ setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
+ flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
# This has it's own function because Wr ops have implicit destinations
- def defineMicroRegOpWr(mnemonic, code):
+ def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
Name = mnemonic
name = mnemonic.lower()
@@ -424,25 +393,29 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
- # Build the all register version of this micro op
class RegOpChild(RegOp):
- def __init__(self, src1, src2):
- super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False)
- self.className = Name
- self.mnemonic = name
+ 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, "RegOp", regCode, RegOpChild, "");
+ setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
+ setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
+ condCheck = checkCCFlagBits, elseCode = elseCode);
- # Build the immediate version of this micro op
class RegOpChildImm(RegOpImm):
- def __init__(self, src1, src2):
- super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False)
- self.className = Name + "Imm"
- self.mnemonic = name + "i"
+ 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)
- setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, "");
+ microopClasses[name + 'i'] = RegOpChildImm
- defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
+ setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode);
+ setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
+ condCheck = checkCCFlagBits, elseCode = elseCode);
# This has it's own function because Rd ops don't always have two parameters
def defineMicroRegOpRd(mnemonic, code):
@@ -450,30 +423,136 @@ let {{
name = mnemonic.lower()
class RegOpChild(RegOp):
- def __init__(self, dest, src1 = "NUM_INTREGS"):
- super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False)
+ def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
+ super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
self.className = Name
self.mnemonic = name
- setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, "");
+ microopClasses[name] = RegOpChild
- defineMicroRegOpRd('Rdip', 'DestReg = RIP')
+ setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
def defineMicroRegOpImm(mnemonic, code):
Name = mnemonic
name = mnemonic.lower()
class RegOpChild(RegOpImm):
- def __init__(self, dest, src1, src2):
- super(RegOpChild, self).__init__(dest, src1, src2, False)
+ def __init__(self, dest, src1, src2, dataSize="env.dataSize"):
+ super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize)
self.className = Name
self.mnemonic = name
- setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, "");
+ microopClasses[name] = RegOpChild
+
+ setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
+
+ defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
+ defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
+ defineMicroRegOp('Adc', '''
+ CCFlagBits flags = ccFlagBits;
+ DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
+ ''')
+ defineMicroRegOp('Sbb', '''
+ CCFlagBits flags = ccFlagBits;
+ DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
+ ''', True)
+ defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
+ defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
+ defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
+ # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
+ defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
+ defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
+ elseCode='DestReg=DestReg;', cc=True)
+
+ # Shift instructions
+ defineMicroRegOp('Sll', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
+ ''')
+ defineMicroRegOp('Srl', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ // Because what happens to the bits shift -in- on a right shift
+ // is not defined in the C/C++ standard, we have to mask them out
+ // to be sure they're zero.
+ uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
+ ''')
+ defineMicroRegOp('Sra', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ // Because what happens to the bits shift -in- on a right shift
+ // is not defined in the C/C++ standard, we have to sign extend
+ // them manually to be sure.
+ uint64_t arithMask =
+ -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
+ ''')
+ defineMicroRegOp('Ror', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
+ uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rcr', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ CCFlagBits flags = ccFlagBits;
+ uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
+ if(shiftAmt > 1)
+ top |= SrcReg1 << (dataSize * 8 - shiftAmt - 1);
+ uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rol', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t bottom =
+ bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rcl', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ CCFlagBits flags = ccFlagBits;
+ uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t bottom = flags.CF << (shiftAmt - 1);
+ if(shiftAmt > 1)
+ bottom |=
+ bits(SrcReg1, dataSize * 8 - 1,
+ dataSize * 8 - shiftAmt + 1);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+
+ defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
+
+ defineMicroRegOpRd('Rdip', 'DestReg = RIP')
defineMicroRegOpImm('Sext', '''
IntReg val = SrcReg1;
int sign_bit = bits(val, imm8-1, imm8-1);
val = sign_bit ? (val | ~mask(imm8)) : val;
DestReg = merge(DestReg, val, dataSize);''')
+
+ defineMicroRegOpImm('Zext', 'DestReg = bits(SrcReg1, imm8-1, 0);')
}};