mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 01:27:59 +02:00
* always write bitpacked typed constant arrays as a multiple of bytes rather
than of their loadsize, because otherwise if they are e.g. part of a record they would occupy more space than allowed o adapted llvm code to deal with the fact that bitpacked arrays are now always arrays of bytes rather than arrays of integers with the same size as their loadsize -- this also fixes several type inconsistencies detected by llvm git-svn-id: trunk@34125 -
This commit is contained in:
parent
9b7e7c5298
commit
0311528502
@ -308,8 +308,6 @@ implementation
|
||||
tllvmencodeflags = set of tllvmencodeflag;
|
||||
|
||||
procedure llvmaddencodedtype_intern(def: tdef; const flags: tllvmencodeflags; var encodedstr: TSymStr);
|
||||
var
|
||||
elesize: asizeint;
|
||||
begin
|
||||
case def.typ of
|
||||
stringdef :
|
||||
@ -465,11 +463,13 @@ implementation
|
||||
else if is_packed_array(def) and
|
||||
(tarraydef(def).elementdef.typ in [enumdef,orddef]) then
|
||||
begin
|
||||
elesize:=packedbitsloadsize(tarraydef(def).elementdef.packedbitsize);
|
||||
encodedstr:=encodedstr+'['+tostr(tarraydef(def).size div elesize)+' x ';
|
||||
{ encode as an array of integers with the size on which we
|
||||
perform the packedbits operations }
|
||||
llvmaddencodedtype_intern(cgsize_orddef(int_cgsize(elesize)),[lef_inaggregate],encodedstr);
|
||||
{ encode as an array of bytes rather than as an array of
|
||||
packedbitsloadsize(elesize), because even if the load size
|
||||
is e.g. 2 bytes, the array may only be 1 or 3 bytes long
|
||||
(and if this array is inside a record, it must not be
|
||||
encoded as a type that is too long) }
|
||||
encodedstr:=encodedstr+'['+tostr(tarraydef(def).size)+' x ';
|
||||
llvmaddencodedtype_intern(u8inttype,[lef_inaggregate],encodedstr);
|
||||
encodedstr:=encodedstr+']';
|
||||
end
|
||||
else
|
||||
|
@ -106,6 +106,7 @@ implementation
|
||||
locref: preference;
|
||||
hreg: tregister;
|
||||
arrptrelementdef: tdef;
|
||||
packedloadsize: aint;
|
||||
indirect: boolean;
|
||||
|
||||
procedure getarrelementptrdef;
|
||||
@ -169,6 +170,21 @@ implementation
|
||||
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,arrptrelementdef,cpointerdef.getreusable(resultdef),locref^.base,hreg);
|
||||
locref^.base:=hreg;
|
||||
end;
|
||||
|
||||
{ packed arrays are represented by an array of byte, but when we operate
|
||||
on them we treat them as arrays of elements of packedbitsloadsize()
|
||||
-> typecast }
|
||||
if is_packed_array(left.resultdef) and
|
||||
(tarraydef(left.resultdef).elementdef.typ in [enumdef,orddef]) then
|
||||
begin
|
||||
getarrelementptrdef;
|
||||
packedloadsize:=packedbitsloadsize(tarraydef(left.resultdef).elementdef.packedbitsize);
|
||||
arrptrelementdef:=cpointerdef.getreusable(cgsize_orddef(int_cgsize(packedloadsize)));
|
||||
hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,
|
||||
cpointerdef.getreusable(u8inttype),
|
||||
arrptrelementdef,
|
||||
locref^);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -253,8 +269,10 @@ implementation
|
||||
value: divide the index by 8 (we're working with a bitpacked array here,
|
||||
all quantities are expressed in bits), and then by the size of the
|
||||
chunks (alignpower) }
|
||||
hreg2:=hlcg.getintregister(current_asmdata.CurrAsmList,ptruinttype);
|
||||
hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,ptruinttype,3+alignpower,hreg,hreg2);
|
||||
offsetreg:=hlcg.getintregister(current_asmdata.CurrAsmList,ptruinttype);
|
||||
hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,ptruinttype,3+alignpower,hreg,offsetreg);
|
||||
hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHL,ptruinttype,alignpower,hreg2,offsetreg);
|
||||
{ index the array using this chunk index }
|
||||
basereg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,cpointerdef.getreusable(defloadsize));
|
||||
current_asmdata.CurrAsmList.Concat(taillvm.getelementptr_reg_size_ref_size_reg(basereg,cpointerdef.getreusable(left.resultdef),
|
||||
@ -278,7 +296,11 @@ implementation
|
||||
|
||||
procedure tllvmvecnode.update_reference_offset(var ref: treference; index, mulsize: aint);
|
||||
begin
|
||||
inc(constarrayoffset,index);
|
||||
if not is_packed_array(left.resultdef) or
|
||||
not (tarraydef(left.resultdef).elementdef.typ in [enumdef,orddef]) then
|
||||
inc(constarrayoffset,index)
|
||||
else
|
||||
inc(constarrayoffset,index*mulsize)
|
||||
end;
|
||||
|
||||
|
||||
|
@ -71,7 +71,7 @@ interface
|
||||
tbitpackedval = record
|
||||
curval, nextval: aword;
|
||||
curbitoffset: smallint;
|
||||
loadbitsize,packedbitsize: byte;
|
||||
packedbitsize: byte;
|
||||
end;
|
||||
|
||||
tasmlisttypedconstbuilder = class(ttypedconstbuilder)
|
||||
@ -320,7 +320,6 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
||||
bp.nextval:=0;
|
||||
bp.curbitoffset:=0;
|
||||
bp.packedbitsize:=packedbitsize;
|
||||
bp.loadbitsize:=packedbitsloadsize(bp.packedbitsize)*8;
|
||||
end;
|
||||
|
||||
|
||||
@ -366,8 +365,8 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
||||
begin
|
||||
if (bp.curbitoffset < AIntBits) then
|
||||
begin
|
||||
{ forced flush -> write multiple of loadsize }
|
||||
bitstowrite:=align(bp.curbitoffset,bp.loadbitsize);
|
||||
{ forced flush -> write multiple of a byte }
|
||||
bitstowrite:=align(bp.curbitoffset,8);
|
||||
bp.curbitoffset:=0;
|
||||
end
|
||||
else
|
||||
@ -375,29 +374,24 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
||||
bitstowrite:=AIntBits;
|
||||
dec(bp.curbitoffset,AIntBits);
|
||||
end;
|
||||
while (bitstowrite>=bp.loadbitsize) do
|
||||
while (bitstowrite>=8) do
|
||||
begin
|
||||
if (target_info.endian=endian_little) then
|
||||
begin
|
||||
{ write lowest "loadbitsize" bits }
|
||||
writeval:=bp.curval and (aint(-1) shr ((sizeof(aint)*8)-bp.loadbitsize));
|
||||
bp.curval:=bp.curval shr bp.loadbitsize;
|
||||
{ write lowest byte }
|
||||
writeval:=byte(bp.curval);
|
||||
bp.curval:=bp.curval shr 8;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ write highest "loadbitsize" bits }
|
||||
writeval:=bp.curval shr (AIntBits-bp.loadbitsize);
|
||||
bp.curval:=bp.curval shl bp.loadbitsize;
|
||||
{ write highest byte }
|
||||
writeval:=bp.curval shr (AIntBits-8);
|
||||
{$push}{$r-,q-}
|
||||
bp.curval:=bp.curval shl 8;
|
||||
{$pop}
|
||||
end;
|
||||
case bp.loadbitsize of
|
||||
8: ftcb.emit_tai(tai_const.create_8bit(writeval),u8inttype);
|
||||
16: ftcb.emit_tai(tai_const.create_16bit(writeval),u16inttype);
|
||||
32: ftcb.emit_tai(tai_const.create_32bit(writeval),u32inttype);
|
||||
64: ftcb.emit_tai(tai_const.create_64bit(writeval),u64inttype);
|
||||
else
|
||||
internalerror(2013111101);
|
||||
end;
|
||||
dec(bitstowrite,bp.loadbitsize);
|
||||
ftcb.emit_tai(tai_const.create_8bit(writeval),u8inttype);
|
||||
dec(bitstowrite,8);
|
||||
end;
|
||||
bp.curval:=bp.nextval;
|
||||
bp.nextval:=0;
|
||||
@ -1477,13 +1471,8 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
||||
{ bitpacked record? }
|
||||
is_packed:=is_packed_record_or_object(def);
|
||||
if (is_packed) then
|
||||
begin
|
||||
{ loadbitsize = 8, bitpacked records are always padded to }
|
||||
{ a multiple of a byte. packedbitsize will be set separately }
|
||||
{ for each field }
|
||||
initbitpackval(bp,0);
|
||||
bp.loadbitsize:=8;
|
||||
end;
|
||||
{ packedbitsize will be set separately for each field }
|
||||
initbitpackval(bp,0);
|
||||
{ normal record }
|
||||
consume(_LKLAMMER);
|
||||
recoffset:=0;
|
||||
|
Loading…
Reference in New Issue
Block a user