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