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

Fix handling of signed bit fields #1126

Merged
merged 1 commit into from
Jan 23, 2024
Merged

Fix handling of signed bit fields #1126

merged 1 commit into from
Jan 23, 2024

Conversation

AArnott
Copy link
Member

@AArnott AArnott commented Jan 23, 2024

Closes #987

Sample code gen for an int bitfield that demonstrates both multi-bit and single-bit values:

internal partial struct FLICK_DATA
{
    internal int _bitfield;

    /// <summary>Gets or sets bits 0-4 in the <see cref="_bitfield" /> field. Allowed values are [-16..15].</summary>
    internal sbyte iFlickActionCommandCode
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        readonly get => (sbyte)((this._bitfield << 27) >> 27);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        set
        {
            Debug.Assert(value is >= (sbyte)-16L and <= (sbyte)15L);
            this._bitfield = (int)((this._bitfield & unchecked((int)~0x0000001F)) | ((int)(value & 0x0000001F) << 0));
        }
    }

    /// <summary>Gets or sets bits 5-7 in the <see cref="_bitfield" /> field. Allowed values are [-4..3].</summary>
    internal sbyte iFlickDirection
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        readonly get => (sbyte)((this._bitfield << 24) >> 29);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        set
        {
            Debug.Assert(value is >= (sbyte)-4L and <= (sbyte)3L);
            this._bitfield = (int)((this._bitfield & unchecked((int)~0x000000E0)) | ((int)(value & 0x00000007) << 5));
        }
    }

    /// <summary>Gets or sets bit 8 in the <see cref="_bitfield" /> field.</summary>
    internal bool fControlModifier
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        readonly get => (this._bitfield & 0x00000100) != 0;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        set => this._bitfield = (int)(value ? this._bitfield | 0x00000100 : (this._bitfield & unchecked((int)~0x00000100)));
    }
}

And here's an unsigned byte bitfield divided up:

internal partial struct _BM
{
    internal byte _bitfield;

    /// <summary>Gets or sets bits 0-1 in the <see cref="_bitfield" /> field. Allowed values are [0..3].</summary>
    internal byte Recipient
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        readonly get => (byte)((this._bitfield >> 0) & 0x03);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        set
        {
            Debug.Assert(value is <= (byte)3L);
            this._bitfield = (byte)((this._bitfield & unchecked((byte)~0x03)) | ((byte)(value & 0x03) << 0));
        }
    }

    /// <summary>Gets or sets bits 2-4 in the <see cref="_bitfield" /> field. Allowed values are [0..7].</summary>
    internal byte Reserved
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        readonly get => (byte)((this._bitfield >> 2) & 0x07);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        set
        {
            Debug.Assert(value is <= (byte)7L);
            this._bitfield = (byte)((this._bitfield & unchecked((byte)~0x1C)) | ((byte)(value & 0x07) << 2));
        }
    }
}

Whether signed or unsigned, single-bit fields are expressed as a bool property.

@AArnott
Copy link
Member Author

AArnott commented Jan 23, 2024

@tannergooding @riverar I'd very much appreciate your reviews.
I suggest focusing on the tests I added, as those are the most readable. If we have adequate coverage, the code gen should be good.
I can also paste in actual code gen snippets if you specify which field types / lengths you're interested in.

@AArnott AArnott merged commit a7a08ba into main Jan 23, 2024
2 checks passed
@AArnott AArnott deleted the fix987 branch January 23, 2024 22:01
@riverar
Copy link

riverar commented Jan 23, 2024

Was on my TOREVIEW list, didn't realize the time fuse was so short. I'll still take a peek as soon as possible.

@AArnott
Copy link
Member Author

AArnott commented Jan 24, 2024

Thanks. Yes I'll absolutely respond to any review you offer, @riverar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve bit fields support
2 participants