mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-02-01 01:30:47 +00:00
Rework bit-field initialization.
This generally simplifies things, and always generates individual initializer records for each explicit initialization of a bit-field (which was previously done for automatic initialization, but not static). This should work correctly for automatic initialization, but needs corresponding code changes in GenSymbols for static initialization.
This commit is contained in:
parent
adfa7c04c1
commit
a3c4eeb8f6
133
Parser.pas
133
Parser.pas
@ -1854,8 +1854,6 @@ procedure Initializer (var variable: identPtr);
|
||||
{ variable - ptr to the identifier begin initialized }
|
||||
|
||||
var
|
||||
bitcount: integer; {# if bits initialized}
|
||||
bitvalue: longint; {bit field initializer value}
|
||||
disp: longint; {disp within overall object being initialized}
|
||||
done: boolean; {for loop termination}
|
||||
errorFound: boolean; {used to remove bad initializations}
|
||||
@ -1882,46 +1880,6 @@ var
|
||||
end; {InsertInitializerRecord}
|
||||
|
||||
|
||||
procedure InitializeBitField;
|
||||
|
||||
{ If bit fields have been initialized, fill them in }
|
||||
{ }
|
||||
{ Inputs: }
|
||||
{ bitcount - # of bits initialized }
|
||||
{ bitvalue - value of initializer }
|
||||
|
||||
var
|
||||
iPtr: initializerPtr; {for creating an initializer entry}
|
||||
|
||||
begin {InitializeBitField}
|
||||
if bitcount <> 0 then begin {skip if there has been no initializer}
|
||||
{ writeln('InitializeBitField; bitcount = ', bitcount:1); {debug}
|
||||
{create the initializer entry}
|
||||
iPtr := pointer(Malloc(sizeof(initializerRecord)));
|
||||
iPtr^.isConstant := isConstant;
|
||||
iPtr^.count := 1;
|
||||
iPtr^.bitdisp := 0;
|
||||
iPtr^.bitsize := 0;
|
||||
iPtr^.iVal := bitvalue;
|
||||
if bitcount <= 8 then
|
||||
iPtr^.basetype := cgUByte
|
||||
else if bitcount <= 24 then
|
||||
iPtr^.basetype := cgUWord
|
||||
else
|
||||
iPtr^.basetype := cgULong;
|
||||
InsertInitializerRecord(iPtr, TypeSize(iPtr^.basetype));
|
||||
if bitcount in [17..24] then begin {3-byte bitfield: split into two parts}
|
||||
iPtr^.iVal := bitvalue & $0000FFFF;
|
||||
bitcount := bitcount - 16;
|
||||
bitvalue := bitvalue >> 16;
|
||||
InitializeBitField;
|
||||
end;
|
||||
bitcount := 0; {reset the bit field values}
|
||||
bitvalue := 0;
|
||||
end; {if}
|
||||
end; {InitializeBitField}
|
||||
|
||||
|
||||
procedure GetInitializerValue (tp: typePtr; bitsize,bitdisp: integer);
|
||||
|
||||
{ get the value of an initializer from a single expression }
|
||||
@ -1931,10 +1889,9 @@ var
|
||||
{ bitsize - size of bit field (0 for non-bit fields) }
|
||||
{ bitdisp - disp of bit field; unused if bitsize = 0 }
|
||||
|
||||
label 1,2,3;
|
||||
label 1,2;
|
||||
|
||||
var
|
||||
bitmask: longint; {used to add a value to a bit field}
|
||||
bKind: baseTypeEnum; {type of constant}
|
||||
etype: typePtr; {expression type}
|
||||
i: integer; {loop variable}
|
||||
@ -1943,6 +1900,7 @@ var
|
||||
kind: tokenEnum; {kind of constant}
|
||||
offset, offset2: longint; {integer offset from a pointer}
|
||||
operator: tokenEnum; {operator for constant pointers}
|
||||
size: longint; {size of item being initialized}
|
||||
tKind: typeKind; {type of constant}
|
||||
tree: tokenPtr; {for evaluating pointer constants}
|
||||
|
||||
@ -2056,21 +2014,22 @@ var
|
||||
Expression(autoInitializerExpression, [commach,rparench,rbracech])
|
||||
else
|
||||
Expression(initializerExpression, [commach,rparench,rbracech]);
|
||||
if bitsize = 0 then begin
|
||||
iPtr := pointer(Malloc(sizeof(initializerRecord)));
|
||||
InsertInitializerRecord(iPtr, tp^.size);
|
||||
if bitsize <> 0 then
|
||||
size := (bitdisp + bitsize + 7) div 8
|
||||
else
|
||||
size := tp^.size;
|
||||
InsertInitializerRecord(iPtr, size);
|
||||
iPtr^.isConstant := isConstant;
|
||||
iPtr^.count := 1;
|
||||
iPtr^.bitdisp := 0;
|
||||
iPtr^.bitsize := 0;
|
||||
end; {if}
|
||||
iPtr^.bitdisp := bitdisp;
|
||||
iPtr^.bitsize := bitsize;
|
||||
etype := expressionType;
|
||||
AssignmentConversion(tp, expressionType, isConstant, expressionValue,
|
||||
false, false);
|
||||
if variable^.storage = external then
|
||||
variable^.storage := global;
|
||||
if isConstant and (variable^.storage in [external,global,private]) then begin
|
||||
if bitsize = 0 then begin
|
||||
if etype^.baseType in [cgQuad,cgUQuad] then begin
|
||||
iPtr^.qVal := llExpressionValue;
|
||||
end {if}
|
||||
@ -2079,8 +2038,6 @@ var
|
||||
iPtr^.iVal := expressionValue;
|
||||
end; {else}
|
||||
iPtr^.basetype := tp^.baseType;
|
||||
InitializeBitField;
|
||||
end; {if}
|
||||
case tp^.kind of
|
||||
|
||||
scalarType: begin
|
||||
@ -2099,7 +2056,7 @@ var
|
||||
iPtr^.qVal.hi := -1
|
||||
else
|
||||
iPtr^.qVal.hi := 0;
|
||||
goto 3;
|
||||
goto 2;
|
||||
end; {if}
|
||||
if bKind in [cgReal,cgDouble,cgComp,cgExtended] then begin
|
||||
if etype^.baseType in [cgByte..cgULong] then
|
||||
@ -2107,26 +2064,10 @@ var
|
||||
else if etype^.baseType in
|
||||
[cgReal,cgDouble,cgComp,cgExtended] then
|
||||
iPtr^.rval := realExpressionValue;
|
||||
goto 3;
|
||||
goto 2;
|
||||
end; {if}
|
||||
Error(47);
|
||||
errorFound := true;
|
||||
goto 2;
|
||||
|
||||
3: if bitsize <> 0 then begin
|
||||
|
||||
{set up a bit field value}
|
||||
if bitdisp < bitcount then
|
||||
InitializeBitField;
|
||||
bitmask := 0;
|
||||
for i := 1 to bitsize do
|
||||
bitmask := (bitmask << 1) | 1;
|
||||
bitmask := bitmask & expressionValue;
|
||||
for i := 1 to bitdisp do
|
||||
bitmask := bitmask << 1;
|
||||
bitvalue := bitvalue | bitmask;
|
||||
bitcount := bitcount + bitsize;
|
||||
end; {if}
|
||||
end;
|
||||
|
||||
arrayType: begin
|
||||
@ -2330,14 +2271,6 @@ var
|
||||
end; {if}
|
||||
|
||||
{handle auto variables}
|
||||
if bitsize <> 0 then begin
|
||||
iPtr := pointer(Malloc(sizeof(initializerRecord)));
|
||||
InsertInitializerRecord(iPtr, 0); {TODO should size be 0?}
|
||||
iPtr^.isConstant := isConstant;
|
||||
iPtr^.count := 1;
|
||||
iPtr^.bitdisp := bitdisp;
|
||||
iPtr^.bitsize := bitsize;
|
||||
end; {if}
|
||||
if variable^.storage in [external,global,private] then begin
|
||||
Error(41);
|
||||
errorFound := true;
|
||||
@ -2345,8 +2278,6 @@ var
|
||||
iPtr^.isConstant := false;
|
||||
iPtr^.iTree := initializerTree;
|
||||
iPtr^.iType := tp;
|
||||
iPtr^.bitdisp := bitdisp;
|
||||
iPtr^.bitsize := bitsize;
|
||||
end; {else}
|
||||
1:
|
||||
end; {GetInitializerValue}
|
||||
@ -2369,7 +2300,8 @@ var
|
||||
label 1,2;
|
||||
|
||||
var
|
||||
bitCount: integer; {# of bits in a union}
|
||||
bfp: identPtr; {pointer to bit-field in field list}
|
||||
bfsize: integer; {number of bytes used by bit-field}
|
||||
braces: boolean; {is the initializer inclosed in braces?}
|
||||
count,maxCount: longint; {for tracking the size of an initializer}
|
||||
ep: tokenPtr; {for forming string expression}
|
||||
@ -2403,8 +2335,6 @@ var
|
||||
ip: identPtr; {pointer to next field in a structure}
|
||||
|
||||
begin {Fill}
|
||||
{ writeln('Fill tp^.kind = ', ord(tp^.kind):1, '; count = ', count:1); {debug}
|
||||
InitializeBitField; {if needed, do the bit field}
|
||||
if tp^.kind = arrayType then
|
||||
|
||||
{fill an array}
|
||||
@ -2671,7 +2601,6 @@ var
|
||||
else if kind in [structType, unionType] then begin
|
||||
if braces or (not main) then begin
|
||||
ip := tp^.fieldList;
|
||||
bitCount := 0;
|
||||
maxDisp := disp;
|
||||
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||
while true do begin
|
||||
@ -2722,24 +2651,25 @@ var
|
||||
end; {if}
|
||||
if (ip = nil) or (ip^.itype^.size = 0) then
|
||||
goto 2;
|
||||
{TODO zero padding in bitfields}
|
||||
if ip^.bitSize = 0 then
|
||||
if bitCount > 0 then begin
|
||||
InitializeBitField;
|
||||
bitCount := 0;
|
||||
end; {if}
|
||||
disp := startingDisp + ip^.disp;
|
||||
if ip^.bitsize <> 0 then begin {zero out padding bits in bitfields}
|
||||
bfp := ip;
|
||||
while (bfp^.next <> nil) and (bfp^.next^.disp = bfp^.disp)
|
||||
and (bfp^.next^.bitsize <> 0) do
|
||||
bfp := bfp^.next;
|
||||
bfsize := (bfp^.bitdisp + bfp^.bitsize + 7) div 8;
|
||||
if disp + bfsize > maxDisp then
|
||||
if (bfp <> ip) or (ip^.bitdisp <> 0)
|
||||
or (ip^.bitsize mod 8 <> 0) then begin
|
||||
Fill(bfsize, charPtr);
|
||||
maxDisp := disp;
|
||||
disp := startingDisp + ip^.disp;
|
||||
end; {if}
|
||||
end; {if}
|
||||
InitializeTerm(ip^.itype, ip^.bitsize, ip^.bitdisp, false,
|
||||
hasNestedDesignator, setNoFill or hasNestedDesignator);
|
||||
if ip^.bitSize <> 0 then begin
|
||||
bitCount := bitCount + ip^.bitSize;
|
||||
if bitCount > maxBitField then begin
|
||||
bitCount := ip^.bitSize;
|
||||
end; {if}
|
||||
end; {if}
|
||||
if disp > maxDisp then
|
||||
maxDisp := disp;
|
||||
{ writeln('Initializer: ', ip^.bitsize:10, ip^.bitdisp:10, bitCount:10); {debug}
|
||||
if kind = unionType then
|
||||
ip := nil
|
||||
else begin
|
||||
@ -2755,12 +2685,7 @@ var
|
||||
else if token.kind <> rbracech then
|
||||
ip := nil;
|
||||
end; {while}
|
||||
2: if bitCount > 0 then begin
|
||||
InitializeBitField;
|
||||
bitCount := (bitCount+7) div 8;
|
||||
bitCount := 0;
|
||||
end; {if}
|
||||
if not noFill then begin
|
||||
2: if not noFill then begin
|
||||
disp := startingDisp + tp^.size;
|
||||
if disp > maxDisp then begin {if there weren't enough initializers...}
|
||||
fillSize := disp - maxDisp;
|
||||
@ -2800,8 +2725,6 @@ var
|
||||
end; {InitializeTerm}
|
||||
|
||||
begin {Initializer}
|
||||
bitcount := 0; {set up for bit fields}
|
||||
bitvalue := 0;
|
||||
disp := 0; {start at beginning of the object}
|
||||
errorFound := false; {no errors found so far}
|
||||
skipComma := false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user