diff options
author | Chris Lattner <sabre@nondot.org> | 2011-02-17 22:09:58 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-02-17 22:09:58 +0000 |
commit | d8df5b65fc76c2f59148e1551f56a8ee26c9607b (patch) | |
tree | defcc946a48109a7e2926561f7153b3210cc34f6 /lib/CodeGen/CGRecordLayoutBuilder.cpp | |
parent | 63ba0460da07749607a33ee419b315712a323542 (diff) |
improve support for big endian targets, fixing PR8171, patch
by Heikki Kultala!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125784 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 7704091b5b..4b19aefcf9 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -225,6 +225,12 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, FieldSize = TypeSizeInBits; } + // in big-endian machines the first fields are in higher bit positions, + // so revert the offset. The byte offsets are reversed(back) later. + if (Types.getTargetData().isBigEndian()) { + FieldOffset = ((ContainingTypeSizeInBits)-FieldOffset-FieldSize); + } + // Compute the access components. The policy we use is to start by attempting // to access using the width of the bit-field type itself and to always access // at aligned indices of that type. If such an access would fail because it @@ -232,7 +238,6 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, // power of two and retry. The current algorithm assumes pow2 sized types, // although this is easy to fix. // - // FIXME: This algorithm is wrong on big-endian systems, I think. assert(llvm::isPowerOf2_32(TypeSizeInBits) && "Unexpected type size!"); CGBitFieldInfo::AccessInfo Components[3]; unsigned NumComponents = 0; @@ -280,7 +285,15 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, // FIXME: We still follow the old access pattern of only using the field // byte offset. We should switch this once we fix the struct layout to be // pretty. - AI.FieldByteOffset = AccessStart / 8; + + // on big-endian machines we reverted the bit offset because first fields are + // in higher bits. But this also reverts the bytes, so fix this here by reverting + // the byte offset on big-endian machines. + if (Types.getTargetData().isBigEndian()) { + AI.FieldByteOffset = (ContainingTypeSizeInBits - AccessStart - AccessWidth )/8; + } else { + AI.FieldByteOffset = AccessStart / 8; + } AI.FieldBitStart = AccessBitsInFieldStart - AccessStart; AI.AccessWidth = AccessWidth; AI.AccessAlignment = llvm::MinAlign(ContainingTypeAlign, AccessStart) / 8; |