Hi!
I stumbled accross a bug in fpc that manifests itself when working with bitpacked records that have fields with pos and size mod 8 == 0; For example:
type
TField = bitpacked record
case boolean of
true: (value : integer);
false: (
data: 0 .. $FFFFFF; // 24 bits
operation: 0 .. $7F; // 7 bits
binop: Boolean // one bit
)
end;
var
a, b: integer;
instr: TField;
begin
//instr.value := $01000004;
a := instr.data ; //and $FFFFFF; // bug in fpc
b := instr.data + 1;
end.will generate asm like
mov 0x37ab3(%rip),%eax # 0x439020 <U_P$PROJECT1_INSTR> mov %eax,0x37a8d(%rip) # 0x439000 <U_P$PROJECT1_A> mov 0x37aa7(%rip),%eax # 0x439020 <U_P$PROJECT1_INSTR> and $0xffffff,%rax
and $0xffffffff,%eax
inc %rax
which is wrong for the first assignment and not very clever for the second one.
I've tracked the issue down to the following check in ncv.pas:
ncv.pas (~ 265)
if equal_defs(p.resultdef,def) and
not is_bitpacked_access(p) then
p.resultdef:=defThe function is_bitpacked_access (relevant parts) is defined as follows.
in nutils.pas (~ 1155)
subscriptn:
result:= is_packed_record_or_object(tsubscriptnode(n).left.resultdef) and (
(tsubscriptnode(n).vs.vardef.packedbitsize mod 8 0) or
(tsubscriptnode(n).vs.fieldoffset mod 8 0));Now, my question is why is an access with a size mod 8 and an offset mod 8 considered NOT bitpacked? Or is the code in ncv.pas to blame?
Cheers,
Willi
