[cfe-commits] r77180 - /cfe/trunk/lib/CodeGen/CGExprConstant.cpp
Anders Carlsson
andersca at mac.com
Sun Jul 26 19:56:38 PDT 2009
Author: andersca
Date: Sun Jul 26 21:56:37 2009
New Revision: 77180
URL: http://llvm.org/viewvc/llvm-project?rev=77180&view=rev
Log:
More work on the constant struct builder, fix a couple of thinkos and add support for inserting part of a bitfield in the previous byte.
Modified:
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=77180&r1=77179&r2=77180&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Sun Jul 26 21:56:37 2009
@@ -130,8 +130,12 @@
return false;
if (FieldOffset > NextFieldOffsetInBytes * 8) {
- // FIXME: Add padding.
- return false;
+ // We need to add padding.
+ uint64_t NumBytes =
+ llvm::RoundUpToAlignment(FieldOffset -
+ NextFieldOffsetInBytes * 8, 8) / 8;
+
+ AppendPadding(NumBytes);
}
uint64_t FieldSize =
@@ -151,22 +155,68 @@
FieldValue.trunc(FieldSize);
if (FieldOffset < NextFieldOffsetInBytes * 8) {
- // FIXME: Part of the bitfield should go into the previous byte.
- return false;
+ // Either part of the field or the entire field can go into the previous
+ // byte.
+ assert(!Elements.empty() && "Elements can't be empty!");
+
+ unsigned BitsInPreviousByte =
+ NextFieldOffsetInBytes * 8 - FieldOffset;
+
+ bool FitsCompletelyInPreviousByte =
+ BitsInPreviousByte >= FieldValue.getBitWidth();
+
+ llvm::APInt Tmp = FieldValue;
+
+ if (!FitsCompletelyInPreviousByte) {
+ unsigned NewFieldWidth = FieldSize - BitsInPreviousByte;
+
+ if (CGM.getTargetData().isBigEndian()) {
+ Tmp = Tmp.lshr(NewFieldWidth);
+ Tmp.trunc(BitsInPreviousByte);
+
+ // We want the remaining high bits.
+ FieldValue.trunc(NewFieldWidth);
+ } else {
+ Tmp.trunc(BitsInPreviousByte);
+
+ // We want the remaining low bits.
+ FieldValue = FieldValue.lshr(BitsInPreviousByte);
+ FieldValue.trunc(NewFieldWidth);
+ }
+ }
+
+ Tmp.zext(8);
+ if (CGM.getTargetData().isBigEndian()) {
+ if (FitsCompletelyInPreviousByte)
+ Tmp = Tmp.shl(BitsInPreviousByte - FieldValue.getBitWidth());
+ } else {
+ Tmp = Tmp.shl(8 - BitsInPreviousByte);
+ }
+
+ // Or in the bits that go into the previous byte.
+ Tmp |= cast<llvm::ConstantInt>(Elements.back())->getValue();
+ Elements.back() = llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp);
+
+ if (FitsCompletelyInPreviousByte)
+ return true;
}
while (FieldValue.getBitWidth() > 8) {
llvm::APInt Tmp;
if (CGM.getTargetData().isBigEndian()) {
- // We want the low bits.
- Tmp = FieldValue.getLoBits(8);
- } else {
// We want the high bits.
- Tmp = FieldValue.getHiBits(8);
+ Tmp = FieldValue;
+ Tmp = Tmp.lshr(Tmp.getBitWidth() - 8);
+ Tmp.trunc(8);
+ } else {
+ // We want the low bits.
+ Tmp = FieldValue;
+ Tmp.trunc(8);
+
+ FieldValue = FieldValue.lshr(8);
}
- Tmp.trunc(8);
Elements.push_back(llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp));
NextFieldOffsetInBytes++;
More information about the cfe-commits
mailing list