X86: Add microops and supporting code to manipulate the whole rflags register.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:49:50 +0000 (00:49 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:49:50 +0000 (00:49 -0400)
src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py
src/arch/x86/isa/microasm.isa
src/arch/x86/isa/microops/regop.isa
src/arch/x86/isa/operands.isa
src/arch/x86/miscregs.hh

index fe60350c11baddfcb9472775bde2f7a8ea4c5ac8..5937ac074864a77a0952891318fdbf604668bb8c 100644 (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
 };
 '''
index 78ae34f525926f96a826fc31b9efbd48dda90593..18abdf09bd5186589f8ae90c203481c7b2435c27 100644 (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',
index 35f1fef025f3d87a0fdace1f4ffed4c75d537d18..0187567e95f6b8f7c6e745a4c3da4f2f76743b36 100644 (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;
index 87fd28a6aa9129856871786b033ecabe5742dd42..b48e8759fcf8780c0ca2b7934ee1efae364663a8 100644 (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),
 
index 83ba3c0c5e47563c76bd33350d01a051ecd4069c..90f1d9fdad81a2600edd2976fcc52cc536eb518e 100644 (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