aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGRecordLayoutBuilder.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-12-09 07:26:04 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-12-09 07:26:04 +0000
commitef8d516e7e015a905ca72ce99590803ca7c7e8f3 (patch)
treeba6dbf200b4c1410c8b23518755493271b8c4bd1 /lib/CodeGen/CGRecordLayoutBuilder.cpp
parent2801d9afa1fabbc99b7c1ad9f2f3df0e0b24adb1 (diff)
Fix the bitfield record layout in codegen for big endian targets.
This was an egregious bug due to the several iterations of refactorings that took place. Size no longer meant what it original did by the time I finished, but this line of code never got updated. Unfortunately we had essentially zero tests for this in the regression test suite. =[ I've added a PPC64 run over the bitfield test case I've been primarily using. I'm still looking at adding more tests and making sure this is the *correct* bitfield access code on PPC64 linux, but it looks pretty close to me, and it is *worlds* better than before this patch as it no longer asserts! =] More commits to follow with at least additional tests and maybe more fixes. Sorry for the long breakage due to this.... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169691 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 123848b8fc..92c5672c73 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -256,9 +256,13 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
Size = TypeSizeInBits;
}
- // Reverse the bit offsets for big endian machines.
- if (Types.getDataLayout().isBigEndian())
- Offset = Size - Offset - 1;
+ // Reverse the bit offsets for big endian machines. Because we represent
+ // a bitfield as a single large integer load, we can imagine the bits
+ // counting from the most-significant-bit instead of the
+ // least-significant-bit.
+ if (Types.getDataLayout().isBigEndian()) {
+ Offset = StorageSize - (Offset + Size);
+ }
return CGBitFieldInfo(Offset, Size, IsSigned, StorageSize, StorageAlignment);
}