X86: Add microops and supporting code to manipulate the whole rflags register.
This commit is contained in:
parent
2bb8933f78
commit
e0c20386ac
|
@ -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
|
|
||||||
};
|
};
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue