X86: Make sure instruction flags are set properly even on 32 bit machines.
authorGabe Black <gblack@eecs.umich.edu>
Tue, 6 Sep 2011 01:36:26 +0000 (18:36 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Tue, 6 Sep 2011 01:36:26 +0000 (18:36 -0700)
The way flag bits were being set for microops in x86 ended up implicitly
calling the bitset constructor which was truncating flags beyond the width of
an unsigned long. This change sets the bits in chunks which are always small
enough to avoid being truncated. On 64 bit machines this should reduce to be
the same as before, and on 32 bit machines it should work properly and not be
unreasonably inefficient.

src/arch/x86/insts/microop.hh

index 6fc21545285e1b0f8da40154ea489a38b834f377..e5248c9ce4e629b299ef86569abe4eddde4c29c6 100644 (file)
@@ -100,7 +100,15 @@ namespace X86ISA
             X86ISA::X86StaticInst(mnem, _machInst, __opClass),
             instMnem(_instMnem)
         {
-            flags |= setFlags;
+            const int ChunkSize = sizeof(unsigned long);
+            const int Chunks = sizeof(setFlags) / ChunkSize;
+
+            // Since the bitset constructor can only handle unsigned long
+            // sized chunks, feed it those one at a time while oring them in.
+            for (int i = 0; i < Chunks; i++) {
+                unsigned shift = i * ChunkSize * 8;
+                flags |= (std::bitset<NumFlags>(setFlags >> shift) << shift);
+            }
         }
 
         std::string generateDisassembly(Addr pc,