summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa
diff options
context:
space:
mode:
authorNilay Vaish <nilay@cs.wisc.edu>2012-05-22 11:29:53 -0500
committerNilay Vaish <nilay@cs.wisc.edu>2012-05-22 11:29:53 -0500
commit4d4d212ae974b3a3ad6d185902d4896c0233a8d9 (patch)
tree4a8203c6677714b5996b6dc22178c61bdb07dec9 /src/arch/x86/isa
parent16a559c9c66b3e810860b59c4099527b38a5337e (diff)
downloadgem5-4d4d212ae974b3a3ad6d185902d4896c0233a8d9.tar.xz
X86: Split Condition Code register
This patch moves the ECF and EZF bits to individual registers (ecfBit and ezfBit) and the CF and OF bits to cfofFlag registers. This is being done so as to lower the read after write dependencies on the the condition code register. Ultimately we will have the following registers [ZAPS], [OF], [CF], [ECF], [EZF] and [DF]. Note that this is only one part of the solution for lowering the dependencies. The other part will check whether or not the condition code register needs to be actually read. This would be done through a separate patch.
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r--src/arch/x86/isa/microops/debug.isa3
-rw-r--r--src/arch/x86/isa/microops/fpop.isa16
-rw-r--r--src/arch/x86/isa/microops/mediaop.isa13
-rw-r--r--src/arch/x86/isa/microops/regop.isa314
-rw-r--r--src/arch/x86/isa/microops/seqop.isa6
-rw-r--r--src/arch/x86/isa/microops/specop.isa3
-rw-r--r--src/arch/x86/isa/operands.isa7
7 files changed, 247 insertions, 115 deletions
diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa
index 220c1af97..2d6af8356 100644
--- a/src/arch/x86/isa/microops/debug.isa
+++ b/src/arch/x86/isa/microops/debug.isa
@@ -141,7 +141,8 @@ let {{
{"code": "",
"func": func,
"func_num": "GenericISA::M5DebugFault::%s" % func_num,
- "cond_test": "checkCondition(ccFlagBits, cc)"})
+ "cond_test": "checkCondition(ccFlagBits | cfofBits | \
+ ecfBit | ezfBit, cc)"})
exec_output += MicroDebugExecute.subst(iop)
header_output += MicroDebugDeclare.subst(iop)
decoder_output += MicroDebugConstructor.subst(iop)
diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa
index 01f26b0f5..08a74173c 100644
--- a/src/arch/x86/isa/microops/fpop.isa
+++ b/src/arch/x86/isa/microops/fpop.isa
@@ -215,7 +215,8 @@ let {{
spm, SetStatus, dataSize)
code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
- cond_check = "checkCondition(ccFlagBits, src2)"
+ cond_check = "checkCondition(ccFlagBits | cfofBits | ecfBit | ezfBit, \
+ src2)"
class Xorfp(FpOp):
code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'
@@ -283,12 +284,15 @@ let {{
// Less than 0 0 1
// Equal 1 0 0
// OF = SF = AF = 0
- ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
- ZFBit | PFBit | CFBit);
- if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2))
- ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
+ ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
+ cfofBits = cfofBits & ~(OFBit | CFBit);
+
+ if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) {
+ ccFlagBits = ccFlagBits | (ZFBit | PFBit);
+ cfofBits = cfofBits | CFBit;
+ }
else if(FpSrcReg1 < FpSrcReg2)
- ccFlagBits = ccFlagBits | CFBit;
+ cfofBits = cfofBits | CFBit;
else if(FpSrcReg1 == FpSrcReg2)
ccFlagBits = ccFlagBits | ZFBit;
'''
diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa
index 0c4827990..7178f1f52 100644
--- a/src/arch/x86/isa/microops/mediaop.isa
+++ b/src/arch/x86/isa/microops/mediaop.isa
@@ -1490,12 +1490,15 @@ let {{
// Less than 0 0 1
// Equal 1 0 0
// OF = SF = AF = 0
- ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
- ZFBit | PFBit | CFBit);
- if (std::isnan(arg1) || std::isnan(arg2))
- ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
+ ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
+ cfofBits = cfofBits & ~(OFBit | CFBit);
+
+ if (std::isnan(arg1) || std::isnan(arg2)) {
+ ccFlagBits = ccFlagBits | (ZFBit | PFBit);
+ cfofBits = cfofBits | CFBit;
+ }
else if(arg1 < arg2)
- ccFlagBits = ccFlagBits | CFBit;
+ cfofBits = cfofBits | CFBit;
else if(arg1 == arg2)
ccFlagBits = ccFlagBits | ZFBit;
'''
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 79ec27f07..cb1d577d7 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -438,26 +438,42 @@ let {{
flag_code = '''
//Don't have genFlags handle the OF or CF bits
uint64_t mask = CFBit | ECFBit | OFBit;
- ccFlagBits = genFlags(ccFlagBits, ext & ~mask, result, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit, ext & ~mask,
+ result, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
+
//If a logic microop wants to set these, it wants to set them to 0.
- ccFlagBits &= ~(CFBit & ext);
- ccFlagBits &= ~(ECFBit & ext);
- ccFlagBits &= ~(OFBit & ext);
+ cfofBits = cfofBits & ~((CFBit | OFBit) & ext);
+ ecfBit = ecfBit & ~(ECFBit & ext);
'''
class FlagRegOp(RegOp):
abstract = True
- flag_code = \
- "ccFlagBits = genFlags(ccFlagBits, ext, result, psrc1, op2);"
+ flag_code = '''
+ uint64_t newFlags = genFlags(ccFlagBits | cfofBits | ecfBit |
+ ezfBit, ext, result, psrc1, op2);
+ cfofBits = newFlags & cfofMask;
+ ecfBit = newFlags & ECFBit;
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
+ '''
class SubRegOp(RegOp):
abstract = True
- flag_code = \
- "ccFlagBits = genFlags(ccFlagBits, ext, result, psrc1, ~op2, true);"
+ flag_code = '''
+ uint64_t newFlags = genFlags(ccFlagBits | cfofBits | ecfBit |
+ ezfBit, ext, result, psrc1, ~op2, true);
+ cfofBits = newFlags & cfofMask;
+ ecfBit = newFlags & ECFBit;
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
+ '''
class CondRegOp(RegOp):
abstract = True
- cond_check = "checkCondition(ccFlagBits, ext)"
+ cond_check = "checkCondition(ccFlagBits | cfofBits | ecfBit | ezfBit, \
+ ext)"
cond_control_flag_init = "flags[IsCondControl] = flags[IsControl];"
class RdRegOp(RegOp):
@@ -484,21 +500,21 @@ let {{
class Adc(FlagRegOp):
code = '''
- CCFlagBits flags = ccFlagBits;
+ CCFlagBits flags = cfofBits;
DestReg = merge(DestReg, result = (psrc1 + op2 + flags.cf), dataSize);
'''
big_code = '''
- CCFlagBits flags = ccFlagBits;
+ CCFlagBits flags = cfofBits;
DestReg = result = (psrc1 + op2 + flags.cf) & mask(dataSize * 8);
'''
class Sbb(SubRegOp):
code = '''
- CCFlagBits flags = ccFlagBits;
+ CCFlagBits flags = cfofBits;
DestReg = merge(DestReg, result = (psrc1 - op2 - flags.cf), dataSize);
'''
big_code = '''
- CCFlagBits flags = ccFlagBits;
+ CCFlagBits flags = cfofBits;
DestReg = result = (psrc1 - op2 - flags.cf) & mask(dataSize * 8);
'''
@@ -536,9 +552,11 @@ let {{
flag_code = '''
if ((-ProdHi & mask(dataSize * 8)) !=
bits(ProdLow, dataSize * 8 - 1)) {
- ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit));
+ cfofBits = cfofBits | (ext & (CFBit | OFBit));
+ ecfBit = ecfBit | (ext & ECFBit);
} else {
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
}
'''
@@ -557,9 +575,11 @@ let {{
'''
flag_code = '''
if (ProdHi) {
- ccFlagBits = ccFlagBits | (ext & (CFBit | OFBit | ECFBit));
+ cfofBits = cfofBits | (ext & (CFBit | OFBit));
+ ecfBit = ecfBit | (ext & ECFBit);
} else {
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | OFBit | ECFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
}
'''
@@ -658,9 +678,9 @@ let {{
big_code = divCode % "DestReg = remaining & mask(dataSize * 8);"
flag_code = '''
if (remaining == 0)
- ccFlagBits = ccFlagBits | (ext & EZFBit);
+ ezfBit = ezfBit | (ext & EZFBit);
else
- ccFlagBits = ccFlagBits & ~(ext & EZFBit);
+ ezfBit = ezfBit & ~(ext & EZFBit);
'''
class Divq(RdRegOp):
@@ -691,22 +711,31 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
int CFBits = 0;
//Figure out if we -would- set the CF bits if requested.
if (shiftAmt <= dataSize * 8 &&
bits(SrcReg1, dataSize * 8 - shiftAmt)) {
CFBits = 1;
}
+
//If some combination of the CF bits need to be set, set them.
- if ((ext & (CFBit | ECFBit)) && CFBits)
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ if ((ext & (CFBit | ECFBit)) && CFBits) {
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
+ }
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (CFBits ^ bits(DestReg, dataSize * 8 - 1)))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -729,19 +758,26 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
//If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) &&
shiftAmt <= dataSize * 8 &&
bits(SrcReg1, shiftAmt - 1)) {
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
}
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && bits(SrcReg1, dataSize * 8 - 1))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -766,17 +802,23 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
//If some combination of the CF bits need to be set, set them.
uint8_t effectiveShift =
(shiftAmt <= dataSize * 8) ? shiftAmt : (dataSize * 8);
if ((ext & (CFBit | ECFBit)) &&
bits(SrcReg1, effectiveShift - 1)) {
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
}
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -797,19 +839,27 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
//Find the most and second most significant bits of the result.
int msb = bits(DestReg, dataSize * 8 - 1);
int smsb = bits(DestReg, dataSize * 8 - 2);
//If some combination of the CF bits need to be set, set them.
- if ((ext & (CFBit | ECFBit)) && msb)
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ if ((ext & (CFBit | ECFBit)) && msb) {
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
+ }
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (msb ^ smsb))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -819,7 +869,7 @@ let {{
(op2 & ((dataSize == 8) ? mask(6) : mask(5)));
uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1);
if (realShiftAmt) {
- CCFlagBits flags = ccFlagBits;
+ CCFlagBits flags = cfofBits;
uint64_t top = flags.cf << (dataSize * 8 - realShiftAmt);
if (realShiftAmt > 1)
top |= psrc1 << (dataSize * 8 - realShiftAmt + 1);
@@ -831,24 +881,30 @@ let {{
flag_code = '''
// If the shift amount is zero, no flags should be modified.
if (shiftAmt) {
- int origCFBit = (ccFlagBits & CFBit) ? 1 : 0;
+ int origCFBit = (cfofBits & CFBit) ? 1 : 0;
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (origCFBit ^
bits(SrcReg1, dataSize * 8 - 1))) {
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
}
//If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) &&
(realShiftAmt == 0) ? origCFBit :
bits(SrcReg1, realShiftAmt - 1)) {
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
}
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -870,19 +926,27 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
//The CF bits, if set, would be set to the lsb of the result.
int lsb = DestReg & 0x1;
int msb = bits(DestReg, dataSize * 8 - 1);
//If some combination of the CF bits need to be set, set them.
- if ((ext & (CFBit | ECFBit)) && lsb)
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ if ((ext & (CFBit | ECFBit)) && lsb) {
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
+ }
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (msb ^ lsb))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -892,7 +956,7 @@ let {{
(op2 & ((dataSize == 8) ? mask(6) : mask(5)));
uint8_t realShiftAmt = shiftAmt % (dataSize * 8 + 1);
if (realShiftAmt) {
- CCFlagBits flags = ccFlagBits;
+ CCFlagBits flags = cfofBits;
uint64_t top = psrc1 << realShiftAmt;
uint64_t bottom = flags.cf << (realShiftAmt - 1);
if(shiftAmt > 1)
@@ -906,22 +970,30 @@ let {{
flag_code = '''
// If the shift amount is zero, no flags should be modified.
if (shiftAmt) {
- int origCFBit = (ccFlagBits & CFBit) ? 1 : 0;
+ int origCFBit = (cfofBits & CFBit) ? 1 : 0;
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+
int msb = bits(DestReg, dataSize * 8 - 1);
int CFBits = bits(SrcReg1, dataSize * 8 - realShiftAmt);
//If some combination of the CF bits need to be set, set them.
if ((ext & (CFBit | ECFBit)) &&
- (realShiftAmt == 0) ? origCFBit : CFBits)
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ (realShiftAmt == 0) ? origCFBit : CFBits) {
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
+ }
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (msb ^ CFBits))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -949,8 +1021,10 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
int CFBits = 0;
+
//Figure out if we -would- set the CF bits if requested.
if ((realShiftAmt == 0 &&
bits(DoubleBits, 0)) ||
@@ -960,16 +1034,23 @@ let {{
bits(DoubleBits, 2 * dataBits - realShiftAmt))) {
CFBits = 1;
}
+
//If some combination of the CF bits need to be set, set them.
- if ((ext & (CFBit | ECFBit)) && CFBits)
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ if ((ext & (CFBit | ECFBit)) && CFBits) {
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
+ }
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
bits(result, dataBits - 1)))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -1003,8 +1084,10 @@ let {{
if (shiftAmt) {
//Zero out any flags we might modify. This way we only have to
//worry about setting them.
- ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit | OFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
int CFBits = 0;
+
//If some combination of the CF bits need to be set, set them.
if ((realShiftAmt == 0 &&
bits(DoubleBits, dataBits - 1)) ||
@@ -1014,16 +1097,23 @@ let {{
bits(DoubleBits, realShiftAmt - dataBits - 1))) {
CFBits = 1;
}
+
//If some combination of the CF bits need to be set, set them.
- if ((ext & (CFBit | ECFBit)) && CFBits)
- ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ if ((ext & (CFBit | ECFBit)) && CFBits) {
+ cfofBits = cfofBits | (ext & CFBit);
+ ecfBit = ecfBit | (ext & ECFBit);
+ }
+
//Figure out what the OF bit should be.
if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
bits(result, dataBits - 1)))
- ccFlagBits = ccFlagBits | OFBit;
+ cfofBits = cfofBits | OFBit;
+
//Use the regular mechanisms to calculate the other flags.
- ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
- DestReg, psrc1, op2);
+ uint64_t newFlags = genFlags(ccFlagBits | ezfBit,
+ ext & ~(CFBit | ECFBit | OFBit), DestReg, psrc1, op2);
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
}
'''
@@ -1035,14 +1125,25 @@ let {{
else_code = "NRIP = NRIP;"
class Wruflags(WrRegOp):
- code = 'ccFlagBits = psrc1 ^ op2'
+ code = '''
+ uint64_t newFlags = psrc1 ^ op2;
+ cfofBits = newFlags & cfofMask;
+ ecfBit = newFlags & ECFBit;
+ ezfBit = newFlags & EZFBit;
+ ccFlagBits = newFlags & ccFlagMask;
+ '''
class Wrflags(WrRegOp):
code = '''
MiscReg newFlags = psrc1 ^ op2;
MiscReg userFlagMask = 0xDD5;
+
// Get only the user flags
- ccFlagBits = newFlags & userFlagMask;
+ ccFlagBits = newFlags & ccFlagMask;
+ cfofBits = newFlags & cfofMask;
+ ecfBit = 0;
+ ezfBit = 0;
+
// Get everything else
nccFlagBits = newFlags & ~userFlagMask;
'''
@@ -1051,24 +1152,26 @@ let {{
code = 'DestReg = NRIP - CSBase;'
class Ruflags(RdRegOp):
- code = 'DestReg = ccFlagBits'
+ code = 'DestReg = ccFlagBits | cfofBits | ecfBit | ezfBit;'
class Rflags(RdRegOp):
- code = 'DestReg = ccFlagBits | nccFlagBits'
+ code = '''
+ DestReg = ccFlagBits | cfofBits | ecfBit | ezfBit | nccFlagBits;
+ '''
class Ruflag(RegOp):
code = '''
- int flag = bits(ccFlagBits, imm8);
+ int flag = bits(ccFlagBits | cfofBits | ecfBit | ezfBit, imm8);
DestReg = merge(DestReg, flag, dataSize);
- ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
- (ccFlagBits & ~EZFBit);
+ ezfBit = (flag == 0) ? EZFBit : 0;
'''
+
big_code = '''
- int flag = bits(ccFlagBits, imm8);
+ int flag = bits(ccFlagBits | cfofBits | ecfBit | ezfBit, imm8);
DestReg = flag & mask(dataSize * 8);
- ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
- (ccFlagBits & ~EZFBit);
+ ezfBit = (flag == 0) ? EZFBit : 0;
'''
+
def __init__(self, dest, imm, flags=None, \
dataSize="env.dataSize"):
super(Ruflag, self).__init__(dest, \
@@ -1077,20 +1180,24 @@ let {{
class Rflag(RegOp):
code = '''
MiscReg flagMask = 0x3F7FDD5;
- MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask;
+ MiscReg flags = (nccFlagBits | ccFlagBits | cfofBits |
+ ecfBit | ezfBit) & flagMask;
+
int flag = bits(flags, imm8);
DestReg = merge(DestReg, flag, dataSize);
- ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
- (ccFlagBits & ~EZFBit);
+ ezfBit = (flag == 0) ? EZFBit : 0;
'''
+
big_code = '''
MiscReg flagMask = 0x3F7FDD5;
- MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask;
+ MiscReg flags = (nccFlagBits | ccFlagBits | cfofBits |
+ ecfBit | ezfBit) & flagMask;
+
int flag = bits(flags, imm8);
DestReg = flag & mask(dataSize * 8);
- ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
- (ccFlagBits & ~EZFBit);
+ ezfBit = (flag == 0) ? EZFBit : 0;
'''
+
def __init__(self, dest, imm, flags=None, \
dataSize="env.dataSize"):
super(Rflag, self).__init__(dest, \
@@ -1106,6 +1213,7 @@ let {{
val = sign_bit ? (val | ~maskVal) : (val & maskVal);
DestReg = merge(DestReg, val, dataSize);
'''
+
big_code = '''
IntReg val = psrc1;
// Mask the bit position so that it wraps.
@@ -1115,13 +1223,19 @@ let {{
val = sign_bit ? (val | ~maskVal) : (val & maskVal);
DestReg = val & mask(dataSize * 8);
'''
+
flag_code = '''
- if (!sign_bit)
- ccFlagBits = ccFlagBits &
- ~(ext & (CFBit | ECFBit | ZFBit | EZFBit));
- else
- ccFlagBits = ccFlagBits |
- (ext & (CFBit | ECFBit | ZFBit | EZFBit));
+ if (!sign_bit) {
+ ccFlagBits = ccFlagBits & ~(ext & (ZFBit));
+ cfofBits = cfofBits & ~(ext & (CFBit));
+ ecfBit = ecfBit & ~(ext & ECFBit);
+ ezfBit = ezfBit & ~(ext & EZFBit);
+ } else {
+ ccFlagBits = ccFlagBits | (ext & (ZFBit));
+ cfofBits = cfofBits | (ext & (CFBit));
+ ecfBit = ecfBit | (ext & ECFBit);
+ ezfBit = ezfBit | (ext & EZFBit);
+ }
'''
class Zext(RegOp):
@@ -1403,9 +1517,13 @@ let {{
'''
flag_code = '''
// Check for a NULL selector and set ZF,EZF appropriately.
- ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit));
- if (!selector.si && !selector.ti)
- ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit));
+ ccFlagBits = ccFlagBits & ~(ext & ZFBit);
+ ezfBit = ezfBit & ~(ext & EZFBit);
+
+ if (!selector.si && !selector.ti) {
+ ccFlagBits = ccFlagBits | (ext & ZFBit);
+ ezfBit = ezfBit | (ext & EZFBit);
+ }
'''
class Wrdh(RegOp):
diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa
index 51d9776da..e3b251162 100644
--- a/src/arch/x86/isa/microops/seqop.isa
+++ b/src/arch/x86/isa/microops/seqop.isa
@@ -172,7 +172,8 @@ let {{
iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase",
{"code": "nuIP = target;",
"else_code": "nuIP = nuIP;",
- "cond_test": "checkCondition(ccFlagBits, cc)",
+ "cond_test": "checkCondition(ccFlagBits | cfofBits | \
+ ecfBit | ezfBit, cc)",
"cond_control_flag_init": "flags[IsCondControl] = true"})
exec_output += SeqOpExecute.subst(iop)
header_output += SeqOpDeclare.subst(iop)
@@ -189,7 +190,8 @@ let {{
iop = InstObjParams("eret", "EretFlags", "SeqOpBase",
{"code": "", "else_code": "",
- "cond_test": "checkCondition(ccFlagBits, cc)",
+ "cond_test": "checkCondition(ccFlagBits | cfofBits | \
+ ecfBit | ezfBit, cc)",
"cond_control_flag_init": ""})
exec_output += SeqOpExecute.subst(iop)
header_output += SeqOpDeclare.subst(iop)
diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa
index 5c242e2c9..8092b28b9 100644
--- a/src/arch/x86/isa/microops/specop.isa
+++ b/src/arch/x86/isa/microops/specop.isa
@@ -181,7 +181,8 @@ let {{
iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
{"code": "",
- "cond_test": "checkCondition(ccFlagBits, cc)"})
+ "cond_test": "checkCondition(ccFlagBits | cfofBits | \
+ ecfBit | ezfBit, cc)"})
exec_output = MicroFaultExecute.subst(iop)
header_output = MicroFaultDeclare.subst(iop)
decoder_output = MicroFaultConstructor.subst(iop)
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index e0ace11d0..8e2ae7fd4 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -119,10 +119,13 @@ def operands {{
# This holds the condition code portion of the flag register. The
# nccFlagBits version holds the rest.
'ccFlagBits': intReg('INTREG_PSEUDO(0)', 60),
+ 'cfofBits': intReg('INTREG_PSEUDO(1)', 61),
+ 'ecfBit': intReg('INTREG_PSEUDO(2)', 62),
+ 'ezfBit': intReg('INTREG_PSEUDO(3)', 63),
# These register should needs to be more protected so that later
# instructions don't map their indexes with an old value.
- 'nccFlagBits': controlReg('MISCREG_RFLAGS', 61),
- 'TOP': controlReg('MISCREG_X87_TOP', 62, ctype='ub'),
+ 'nccFlagBits': controlReg('MISCREG_RFLAGS', 64),
+ 'TOP': controlReg('MISCREG_X87_TOP', 65, ctype='ub'),
# The segment base as used by memory instructions.
'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70),