summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2011-08-13 23:03:11 -0700
committerGabe Black <gblack@eecs.umich.edu>2011-08-13 23:03:11 -0700
commit1b9de61a710f6cb125a63e347500155fe2330b55 (patch)
treedb6d7f09db3ba05c21d092f0433af2b2154ed36e /src/arch/x86/isa
parente0043f8dbe926ed5bfadb504b0a69b1a1fbfcede (diff)
downloadgem5-1b9de61a710f6cb125a63e347500155fe2330b55.tar.xz
X86: Use IsSquashAfter if an instruction could affect fetch translation.
Control register operands are set up so that writing to them is serialize after, serialize before, and non-speculative. These are probably overboard, but they should usually be safe. Unfortunately there are times when even these aren't enough. If an instruction modifies state that affects fetch, later serialized instructions which come after it might have already gone through fetch and decode by the time it commits. These instructions may have been translated incorrectly or interpretted incorrectly and need to be destroyed. This change modifies instructions which will or may have this behavior so that they use the IsSquashAfter flag when necessary.
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r--src/arch/x86/isa/operands.isa29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index aedfedc0c..e0ace11d0 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -67,6 +67,19 @@ let {{
'IsSerializing',
'IsNonSpeculative']),
id)
+ def squashCheckReg(idx, id, check, ctype = 'uqw'):
+ return ('ControlReg', ctype, idx,
+ (None, None, ['((%s) ? ' % check+ \
+ 'IsSquashAfter : IsSerializeAfter)',
+ 'IsSerializing',
+ 'IsNonSpeculative']),
+ id)
+ def squashCReg(idx, id, ctype = 'uqw'):
+ return squashCheckReg(idx, id, 'true', ctype)
+ def squashCSReg(idx, id, ctype = 'uqw'):
+ return squashCheckReg(idx, id, 'dest == SEGMENT_REG_CS', ctype)
+ def squashCR0Reg(idx, id, ctype = 'uqw'):
+ return squashCheckReg(idx, id, 'dest == 0', ctype)
}};
def operands {{
@@ -115,21 +128,21 @@ def operands {{
# Operands to get and set registers indexed by the operands of the
# original instruction.
- 'ControlDest': controlReg('MISCREG_CR(dest)', 100),
+ 'ControlDest': squashCR0Reg('MISCREG_CR(dest)', 100),
'ControlSrc1': controlReg('MISCREG_CR(src1)', 101),
'DebugDest': controlReg('MISCREG_DR(dest)', 102),
'DebugSrc1': controlReg('MISCREG_DR(src1)', 103),
- 'SegBaseDest': controlReg('MISCREG_SEG_BASE(dest)', 104),
+ 'SegBaseDest': squashCSReg('MISCREG_SEG_BASE(dest)', 104),
'SegBaseSrc1': controlReg('MISCREG_SEG_BASE(src1)', 105),
- 'SegLimitDest': controlReg('MISCREG_SEG_LIMIT(dest)', 106),
+ 'SegLimitDest': squashCSReg('MISCREG_SEG_LIMIT(dest)', 106),
'SegLimitSrc1': controlReg('MISCREG_SEG_LIMIT(src1)', 107),
'SegSelDest': controlReg('MISCREG_SEG_SEL(dest)', 108),
'SegSelSrc1': controlReg('MISCREG_SEG_SEL(src1)', 109),
- 'SegAttrDest': controlReg('MISCREG_SEG_ATTR(dest)', 110),
+ 'SegAttrDest': squashCSReg('MISCREG_SEG_ATTR(dest)', 110),
'SegAttrSrc1': controlReg('MISCREG_SEG_ATTR(src1)', 111),
# Operands to access specific control registers directly.
- 'EferOp': controlReg('MISCREG_EFER', 200),
+ 'EferOp': squashCReg('MISCREG_EFER', 200),
'CR4Op': controlReg('MISCREG_CR4', 201),
'DR7Op': controlReg('MISCREG_DR7', 202),
'LDTRBase': controlReg('MISCREG_TSL_BASE', 203),
@@ -137,12 +150,12 @@ def operands {{
'LDTRSel': controlReg('MISCREG_TSL', 205),
'GDTRBase': controlReg('MISCREG_TSG_BASE', 206),
'GDTRLimit': controlReg('MISCREG_TSG_LIMIT', 207),
- 'CSBase': controlReg('MISCREG_CS_EFF_BASE', 208),
- 'CSAttr': controlReg('MISCREG_CS_ATTR', 209),
+ 'CSBase': squashCReg('MISCREG_CS_EFF_BASE', 208),
+ 'CSAttr': squashCReg('MISCREG_CS_ATTR', 209),
'MiscRegDest': controlReg('dest', 210),
'MiscRegSrc1': controlReg('src1', 211),
'TscOp': controlReg('MISCREG_TSC', 212),
- 'M5Reg': controlReg('MISCREG_M5_REG', 213),
+ 'M5Reg': squashCReg('MISCREG_M5_REG', 213),
'Mem': ('Mem', 'uqw', None, \
('IsMemRef', 'IsLoad', 'IsStore'), 300)
}};