Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable] Prepare TargetC for ARM bit-fields special case #16742

Merged
merged 2 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 33 additions & 45 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -7186,12 +7186,19 @@
error(bfd.loc, "bit field width %d is larger than type", bfd.fieldWidth);

const style = target.c.bitFieldStyle;
if (style != TargetC.BitFieldStyle.MS && style != TargetC.BitFieldStyle.Gcc_Clang)
assert(0, "unsupported bit-field style");

const isMicrosoftStyle = style == TargetC.BitFieldStyle.MS;
const contributesToAggregateAlignment = target.c.contributesToAggregateAlignment(bfd);

void startNewField()
{
if (log) printf("startNewField()\n");
uint alignsize;
if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (isMicrosoftStyle)
alignsize = memsize; // not memalignsize
else
{
if (bfd.fieldWidth > 32)
alignsize = memalignsize;
Expand All @@ -7202,15 +7209,13 @@
else
alignsize = 1;
}
else
alignsize = memsize; // not memalignsize

uint dummy;
bfd.offset = placeField(
fieldState.offset,
memsize, alignsize, bfd.alignment,
ad.structsize,
(anon && style == TargetC.BitFieldStyle.Gcc_Clang) ? dummy : ad.alignsize,
contributesToAggregateAlignment ? ad.alignsize : dummy,
isunion);

fieldState.inFlight = true;
Expand All @@ -7219,53 +7224,38 @@
fieldState.fieldSize = memsize;
}

if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (ad.alignsize == 0)
ad.alignsize = 1;
if (!isMicrosoftStyle && contributesToAggregateAlignment && ad.alignsize < memalignsize)
ad.alignsize = memalignsize;

Check warning on line 7230 in compiler/src/dmd/dsymbolsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/dsymbolsem.d#L7230

Added line #L7230 was not covered by tests

if (bfd.fieldWidth == 0)
{
if (bfd.fieldWidth == 0)
if (!isMicrosoftStyle && !isunion)
{
if (!isunion)
{
// Use type of zero width field to align to next field
fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
// Use type of zero width field to align to next field
fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
ad.structsize = fieldState.offset;

Check warning on line 7238 in compiler/src/dmd/dsymbolsem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/dsymbolsem.d#L7237-L7238

Added lines #L7237 - L7238 were not covered by tests
}

if (ad.alignsize == 0)
ad.alignsize = 1;
if (!anon &&
ad.alignsize < memalignsize)
ad.alignsize = memalignsize;
}
else if (style == TargetC.BitFieldStyle.MS)
{
if (ad.alignsize == 0)
ad.alignsize = 1;
if (bfd.fieldWidth == 0)
else if (isMicrosoftStyle && fieldState.inFlight && !isunion)
{
if (fieldState.inFlight && !isunion)
{
// documentation says align to next int
//const alsz = cast(uint)Type.tint32.size();
const alsz = memsize; // but it really does this
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
// documentation says align to next int
//const alsz = cast(uint)Type.tint32.size();
const alsz = memsize; // but it really does this
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
}

if (!fieldState.inFlight)
{
//printf("not in flight\n");
startNewField();
}
else if (style == TargetC.BitFieldStyle.Gcc_Clang)
else if (!isMicrosoftStyle)
{
// If the bit-field spans more units of alignment than its type,
// start a new field at the next alignment boundary.
Expand All @@ -7288,7 +7278,7 @@
}
}
}
else if (style == TargetC.BitFieldStyle.MS)
else
{
if (memsize != fieldState.fieldSize ||
fieldState.bitOffset + bfd.fieldWidth > fieldState.fieldSize * 8)
Expand All @@ -7297,14 +7287,14 @@
startNewField();
}
}
else
assert(0);

bfd.offset = fieldState.fieldOffset;
bfd.bitOffset = fieldState.bitOffset;

const pastField = bfd.bitOffset + bfd.fieldWidth;
if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (isMicrosoftStyle)
fieldState.fieldSize = memsize;
else
{
auto size = (pastField + 7) / 8;
fieldState.fieldSize = size;
Expand All @@ -7318,8 +7308,6 @@
else
ad.structsize = bfd.offset + size;
}
else
fieldState.fieldSize = memsize;
//printf("at end: ad.structsize = %d\n", cast(int)ad.structsize);
//print(fieldState);

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -5950,6 +5950,7 @@ struct TargetC final
uint8_t wchar_tsize;
Runtime runtime;
BitFieldStyle bitFieldStyle;
bool contributesToAggregateAlignment(BitFieldDeclaration* bfd);
TargetC() :
crtDestructorsSupported(true),
boolsize(),
Expand Down
20 changes: 20 additions & 0 deletions compiler/src/dmd/target.d
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,8 @@
*/
struct TargetC
{
import dmd.declaration : BitFieldDeclaration;

enum Runtime : ubyte
{
Unspecified,
Expand Down Expand Up @@ -1449,6 +1451,24 @@
crtDestructorsSupported = false;
}
}

/**
* Indicates whether the specified bit-field contributes to the alignment
* of the containing aggregate.
* E.g., (not all) ARM ABIs do NOT ignore anonymous (incl. 0-length)
* bit-fields.
*/
extern (C++) bool contributesToAggregateAlignment(BitFieldDeclaration bfd)
{
if (bitFieldStyle == BitFieldStyle.MS)
return true;
if (bitFieldStyle == BitFieldStyle.Gcc_Clang)

Check warning on line 1465 in compiler/src/dmd/target.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/target.d#L1465

Added line #L1465 was not covered by tests
{
// sufficient for DMD's currently supported architectures
return !bfd.isAnonymous();

Check warning on line 1468 in compiler/src/dmd/target.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/target.d#L1468

Added line #L1468 was not covered by tests
}
assert(0);
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dmd/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "globals.h"
#include "tokens.h"

class BitFieldDeclaration;
class ClassDeclaration;
class Dsymbol;
class Expression;
Expand Down Expand Up @@ -77,6 +78,8 @@ struct TargetC
uint8_t wchar_tsize; // size of a C 'wchar_t' type
Runtime runtime;
BitFieldStyle bitFieldStyle; // different C compilers do it differently

bool contributesToAggregateAlignment(BitFieldDeclaration *bfd);
};

struct TargetCPP
Expand Down
Loading