Output bit-field data as chars instead of ints

This prepares for #1058, which will pad bit-fields only to
the next byte, instead of the next sizeof(int) (two bytes).

OutputBitFieldData now outputs chars instead of ints, and
calls to this function loop until there is less than one byte
to output.  A final partial byte is written out with zero padding
as a final partial int was previously.
This commit is contained in:
Jesse Rosenstock 2020-06-28 22:18:12 +02:00 committed by greg-king5
parent 90d1c89bff
commit a00611798d

View file

@ -1814,17 +1814,17 @@ static void OutputBitFieldData (StructInitData* SI)
if (SI->ValBits > 0) { if (SI->ValBits > 0) {
/* Output the data */ /* Output the data */
g_defdata (CF_INT | CF_UNSIGNED | CF_CONST, SI->BitVal, 0); g_defdata (CF_CHAR | CF_UNSIGNED | CF_CONST, SI->BitVal, 0);
/* Update the data from SI and account for the size */ /* Update the data from SI and account for the size */
if (SI->ValBits >= INT_BITS) { if (SI->ValBits >= CHAR_BITS) {
SI->BitVal >>= INT_BITS; SI->BitVal >>= CHAR_BITS;
SI->ValBits -= INT_BITS; SI->ValBits -= CHAR_BITS;
} else { } else {
SI->BitVal = 0; SI->BitVal = 0;
SI->ValBits = 0; SI->ValBits = 0;
} }
SI->Offs += SIZEOF_INT; SI->Offs += SIZEOF_CHAR;
} }
} }
@ -2062,8 +2062,8 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers)
** These will be packed into 3 bytes. ** These will be packed into 3 bytes.
*/ */
SI.ValBits += Entry->V.B.BitWidth; SI.ValBits += Entry->V.B.BitWidth;
CHECK (SI.ValBits <= 2 * (INT_BITS - 1)); CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2);
if (SI.ValBits >= INT_BITS) { while (SI.ValBits >= CHAR_BITS) {
OutputBitFieldData (&SI); OutputBitFieldData (&SI);
} }
goto NextMember; goto NextMember;
@ -2089,14 +2089,15 @@ static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers)
/* Account for the data and output it if we have a full word */ /* Account for the data and output it if we have a full word */
SI.ValBits += Entry->V.B.BitWidth; SI.ValBits += Entry->V.B.BitWidth;
/* Make sure unsigned is big enough to hold the value, 30 bits. /* Make sure unsigned is big enough to hold the value, 22 bits.
** This is 30 and not 32 bits because a 16-bit bit-field will ** This is 22 bits because the most we can have is 7 bits left
** always be byte aligned, so will have padding before it. ** over from the previous OutputBitField call, plus 15 bits
** 15 bits twice is the most we can have. ** from this field. A 16-bit bit-field will always be byte
** aligned, so will have padding before it.
*/ */
CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal)); CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal));
CHECK (SI.ValBits < 2 * (INT_BITS - 1)); CHECK (SI.ValBits <= CHAR_BITS + INT_BITS - 2);
if (SI.ValBits >= INT_BITS) { while (SI.ValBits >= CHAR_BITS) {
OutputBitFieldData (&SI); OutputBitFieldData (&SI);
} }