[cfe-commits] r64727 - /cfe/trunk/lib/CodeGen/CGCall.cpp

Daniel Dunbar daniel at zuster.org
Mon Feb 16 18:45:45 PST 2009


Author: ddunbar
Date: Mon Feb 16 20:45:44 2009
New Revision: 64727

URL: http://llvm.org/viewvc/llvm-project?rev=64727&view=rev
Log:
x86_64 ABI: Implement classification for bit-fields.

Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=64727&r1=64726&r2=64727&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Feb 16 20:45:44 2009
@@ -620,10 +620,13 @@
     for (RecordDecl::field_iterator i = RD->field_begin(), 
            e = RD->field_end(); i != e; ++i, ++idx) {
       uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
+      bool BitField = i->isBitField();
 
       // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
       // fields, it has class MEMORY.
-      if (Offset % Context.getTypeAlign(i->getType())) {
+      //
+      // Note, skip this test for bitfields, see below.
+      if (!BitField && Offset % Context.getTypeAlign(i->getType())) {
         Lo = Memory;
         return;
       }
@@ -635,7 +638,28 @@
       // separately. Each eightbyte gets initialized to class
       // NO_CLASS.
       Class FieldLo, FieldHi;
-      classify(i->getType(), Context, Offset, FieldLo, FieldHi);
+      
+      // Bitfields require special handling, they do not force the
+      // structure to be passed in memory even if unaligned, and
+      // therefore they can straddle an eightbyte.
+      if (BitField) {
+        uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
+        uint64_t Size = 
+          i->getBitWidth()->getIntegerConstantExprValue(Context).getZExtValue();
+
+        uint64_t EB_Lo = Offset / 64;
+        uint64_t EB_Hi = (Offset + Size - 1) / 64;
+        FieldLo = FieldHi = NoClass;
+        if (EB_Lo) {
+          assert(EB_Hi == EB_Lo && "Invalid classification, type > 16 bytes.");
+          FieldLo = NoClass;
+          FieldHi = Integer;
+        } else { 
+          FieldLo = Integer;
+          FieldHi = EB_Hi ? Integer : NoClass;
+        }
+      } else
+        classify(i->getType(), Context, Offset, FieldLo, FieldHi);
       Lo = merge(Lo, FieldLo);
       Hi = merge(Hi, FieldHi);
       if (Lo == Memory || Hi == Memory)





More information about the cfe-commits mailing list