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. # All rights reserved.
# #
# Redistribution and use of this software in source and binary forms, # Redistribution and use of this software in source and binary forms,
@ -57,8 +57,7 @@ microcode = '''
def macroop PUSHF { def macroop PUSHF {
.adjust_env oszIn64Override .adjust_env oszIn64Override
# This should really read the whole flags register, not just user flags. rflags t1
ruflags t1
stupd t1, ss, [1, t0, rsp], "-env.dataSize" stupd t1, ss, [1, t0, rsp], "-env.dataSize"
}; };
@ -67,7 +66,6 @@ def macroop POPF {
ld t1, ss, [1, t0, rsp] ld t1, ss, [1, t0, rsp]
addi rsp, rsp, dsz addi rsp, rsp, dsz
# This should really write the whole flags register, not just user flags. wrflags t1, t0
wruflags t1, t0
}; };
''' '''

View file

@ -1,6 +1,6 @@
// -*- mode:c++ -*- // -*- mode:c++ -*-
// Copyright (c) 2007 The Hewlett-Packard Development Company // Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@ -135,7 +135,8 @@ let {{
for reg in range(15): for reg in range(15):
assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg 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" assembler.symbols[flag] = flag + "Bit"
for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF', for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF',

View file

@ -845,12 +845,25 @@ let {{
class Wruflags(WrRegOp): class Wruflags(WrRegOp):
code = 'ccFlagBits = psrc1 ^ op2' 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): class Rdip(RdRegOp):
code = 'DestReg = RIP - CSBase' code = 'DestReg = RIP - CSBase'
class Ruflags(RdRegOp): class Ruflags(RdRegOp):
code = 'DestReg = ccFlagBits' code = 'DestReg = ccFlagBits'
class Rflags(RdRegOp):
code = 'DestReg = ccFlagBits | nccFlagBits'
class Ruflag(RegOp): class Ruflag(RegOp):
code = ''' code = '''
int flag = bits(ccFlagBits, imm8); int flag = bits(ccFlagBits, imm8);
@ -863,6 +876,20 @@ let {{
super(Ruflag, self).__init__(dest, \ super(Ruflag, self).__init__(dest, \
"NUM_INTREGS", imm, flags, dataSize) "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): class Sext(RegOp):
code = ''' code = '''
IntReg val = psrc1; IntReg val = psrc1;

View file

@ -117,10 +117,13 @@ def operands {{
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50),
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51), 'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52), '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), '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. # 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. # The segment base as used by memory instructions.
'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70), '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 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 enum MiscRegIndex
{ {
// Control registers // Control registers