X86: Add microops and supporting code to manipulate the whole rflags register.

This commit is contained in:
Gabe Black 2008-06-12 00:49:50 -04:00
parent 2bb8933f78
commit e0c20386ac
5 changed files with 50 additions and 9 deletions

View file

@ -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
};
'''

View file

@ -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',

View file

@ -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;

View file

@ -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),

View file

@ -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