summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py8
-rw-r--r--src/arch/x86/isa/microasm.isa5
-rw-r--r--src/arch/x86/isa/microops/regop.isa27
-rw-r--r--src/arch/x86/isa/operands.isa7
-rw-r--r--src/arch/x86/miscregs.hh12
5 files changed, 50 insertions, 9 deletions
diff --git a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
index fe60350c1..5937ac074 100644
--- a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
+++ b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
@@ -57,8 +57,7 @@ microcode = '''
def macroop PUSHF {
.adjust_env oszIn64Override
- # This should really read the whole flags register, not just user flags.
- ruflags t1
+ rflags t1
stupd t1, ss, [1, t0, rsp], "-env.dataSize"
};
@@ -67,7 +66,6 @@ def macroop POPF {
ld t1, ss, [1, t0, rsp]
addi rsp, rsp, dsz
- # This should really write the whole flags register, not just user flags.
- wruflags t1, t0
+ wrflags t1, t0
};
'''
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index 78ae34f52..18abdf09b 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@@ -135,7 +135,8 @@ let {{
for reg in range(15):
assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg
- for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'):
+ for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \
+ 'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'):
assembler.symbols[flag] = flag + "Bit"
for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF',
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 35f1fef02..0187567e9 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -845,12 +845,25 @@ let {{
class Wruflags(WrRegOp):
code = 'ccFlagBits = psrc1 ^ op2'
+ class Wrflags(WrRegOp):
+ code = '''
+ MiscReg newFlags = psrc1 ^ op2;
+ MiscReg userFlagMask = 0xDD5;
+ // Get only the user flags
+ ccFlagBits = newFlags & userFlagMask;
+ // Get everything else
+ nccFlagBits = newFlags & ~userFlagMask;
+ '''
+
class Rdip(RdRegOp):
code = 'DestReg = RIP - CSBase'
class Ruflags(RdRegOp):
code = 'DestReg = ccFlagBits'
+ class Rflags(RdRegOp):
+ code = 'DestReg = ccFlagBits | nccFlagBits'
+
class Ruflag(RegOp):
code = '''
int flag = bits(ccFlagBits, imm8);
@@ -863,6 +876,20 @@ let {{
super(Ruflag, self).__init__(dest, \
"NUM_INTREGS", imm, flags, dataSize)
+ class Rflag(RegOp):
+ code = '''
+ MiscReg flagMask = 0x3F7FDD5;
+ MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask;
+ int flag = bits(flags, imm8);
+ DestReg = merge(DestReg, flag, dataSize);
+ ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
+ (ccFlagBits & ~EZFBit);
+ '''
+ def __init__(self, dest, imm, flags=None, \
+ dataSize="env.dataSize"):
+ super(Rflag, self).__init__(dest, \
+ "NUM_INTREGS", imm, flags, dataSize)
+
class Sext(RegOp):
code = '''
IntReg val = psrc1;
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index 87fd28a6a..b48e8759f 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -117,10 +117,13 @@ def operands {{
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50),
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
+ # This holds the condition code portion of the flag register. The
+ # nccFlagBits version holds the rest.
'ccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60),
- # The TOP register should needs to be more protected so that later
+ # These register should needs to be more protected so that later
# instructions don't map their indexes with an old value.
- 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
+ 'nccFlagBits': ('ControlReg', 'uqw', 'MISCREG_RFLAGS', None, 61),
+ 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 62),
# The segment base as used by memory instructions.
'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh
index 83ba3c0c5..90f1d9fda 100644
--- a/src/arch/x86/miscregs.hh
+++ b/src/arch/x86/miscregs.hh
@@ -82,6 +82,18 @@ namespace X86ISA
OFBit = 1 << 11
};
+ enum RFLAGBit {
+ TFBit = 1 << 8,
+ IFBit = 1 << 9,
+ NTBit = 1 << 14,
+ RFBit = 1 << 16,
+ VMBit = 1 << 17,
+ ACBit = 1 << 18,
+ VIFBit = 1 << 19,
+ VIPBit = 1 << 20,
+ IDBit = 1 << 21
+ };
+
enum MiscRegIndex
{
// Control registers