mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 18:49:15 +02:00
* handle bitpacked booleans more efficiently
git-svn-id: trunk@38509 -
This commit is contained in:
parent
fe8f7a9876
commit
a66016026b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -16055,6 +16055,7 @@ tests/webtbs/tw3328a.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw3328b.pp svneol=native#text/plain
|
tests/webtbs/tw3328b.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3334.pp svneol=native#text/plain
|
tests/webtbs/tw3334.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3340.pp svneol=native#text/plain
|
tests/webtbs/tw3340.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw33417.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw3348.pp svneol=native#text/plain
|
tests/webtbs/tw3348.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3349.pp svneol=native#text/plain
|
tests/webtbs/tw3349.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3351.pp svneol=native#text/plain
|
tests/webtbs/tw3351.pp svneol=native#text/plain
|
||||||
|
@ -59,37 +59,71 @@ implementation
|
|||||||
var
|
var
|
||||||
tmpreg,lreg : tregister;
|
tmpreg,lreg : tregister;
|
||||||
i : longint;
|
i : longint;
|
||||||
|
falselabel,truelabel,skiplabel: TAsmLabel;
|
||||||
begin
|
begin
|
||||||
if not handle_locjump then
|
if not handle_locjump then
|
||||||
begin
|
begin
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
case left.location.loc of
|
{ short code? }
|
||||||
LOC_FLAGS :
|
if (left.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG]) and
|
||||||
begin
|
(left.location.sreg.bitlen=1) then
|
||||||
location_copy(location,left.location);
|
begin
|
||||||
inverse_flags(location.resflags);
|
current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_SBRC,left.location.sreg.subsetreg,left.location.sreg.startbit));
|
||||||
end;
|
current_asmdata.getjumplabel(truelabel);
|
||||||
LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE,
|
current_asmdata.getjumplabel(falselabel);
|
||||||
LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF :
|
{ sbrc does a jump without an explicit label,
|
||||||
begin
|
if we do not insert skiplabel here and increase its reference count, the optimizer removes the whole true block altogether }
|
||||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
|
current_asmdata.getjumplabel(skiplabel);
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CPI,left.location.register,0));
|
skiplabel.increfs;
|
||||||
|
location_reset_jump(location,truelabel,falselabel);
|
||||||
|
cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
|
||||||
|
cg.a_jmp_always(current_asmdata.CurrAsmList,truelabel);
|
||||||
|
end
|
||||||
|
else if (left.location.loc in [LOC_SUBSETREF,LOC_CSUBSETREF]) and
|
||||||
|
(left.location.sref.bitlen=1) and (left.location.sref.bitindexreg=NR_NO) then
|
||||||
|
begin
|
||||||
|
tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
|
||||||
|
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,u8inttype,osuinttype,left.location.sref.ref,tmpreg);
|
||||||
|
current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_SBRC,tmpreg,left.location.sref.startbit));
|
||||||
|
current_asmdata.getjumplabel(truelabel);
|
||||||
|
current_asmdata.getjumplabel(falselabel);
|
||||||
|
{ sbrc does a jump without an explicit label,
|
||||||
|
if we do not insert skiplabel here and increase its reference count, the optimizer removes the whole true block altogether }
|
||||||
|
current_asmdata.getjumplabel(skiplabel);
|
||||||
|
skiplabel.increfs;
|
||||||
|
location_reset_jump(location,truelabel,falselabel);
|
||||||
|
cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
|
||||||
|
cg.a_label(current_asmdata.CurrAsmList,skiplabel);
|
||||||
|
cg.a_jmp_always(current_asmdata.CurrAsmList,truelabel);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
case left.location.loc of
|
||||||
|
LOC_FLAGS :
|
||||||
|
begin
|
||||||
|
location_copy(location,left.location);
|
||||||
|
inverse_flags(location.resflags);
|
||||||
|
end;
|
||||||
|
LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF,
|
||||||
|
LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE :
|
||||||
|
begin
|
||||||
|
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
|
||||||
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CPI,left.location.register,0));
|
||||||
|
|
||||||
tmpreg:=left.location.register;
|
tmpreg:=left.location.register;
|
||||||
for i:=2 to tcgsize2size[left.location.size] do
|
for i:=2 to tcgsize2size[left.location.size] do
|
||||||
begin
|
begin
|
||||||
if i=5 then
|
if i=5 then
|
||||||
tmpreg:=left.location.registerhi
|
tmpreg:=left.location.registerhi
|
||||||
else
|
else
|
||||||
tmpreg:=cg.GetNextReg(tmpreg);
|
tmpreg:=cg.GetNextReg(tmpreg);
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,NR_R1,tmpreg));
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,NR_R1,tmpreg));
|
||||||
end;
|
end;
|
||||||
location_reset(location,LOC_FLAGS,OS_NO);
|
location_reset(location,LOC_FLAGS,OS_NO);
|
||||||
location.resflags:=F_EQ;
|
location.resflags:=F_EQ;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(2003042401);
|
||||||
end;
|
end;
|
||||||
else
|
|
||||||
internalerror(2003042401);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -253,11 +253,38 @@ implementation
|
|||||||
begin
|
begin
|
||||||
opsize:=def_cgsize(p.resultdef);
|
opsize:=def_cgsize(p.resultdef);
|
||||||
case p.location.loc of
|
case p.location.loc of
|
||||||
LOC_SUBSETREG,LOC_CSUBSETREG,
|
LOC_SUBSETREG,LOC_CSUBSETREG:
|
||||||
|
begin
|
||||||
|
if p.location.sreg.bitlen=1 then
|
||||||
|
begin
|
||||||
|
tmpreg:=cg.getintregister(list,p.location.sreg.subsetregsize);
|
||||||
|
hlcg.a_op_const_reg_reg(list,OP_AND,cgsize_orddef(p.location.sreg.subsetregsize),1 shl p.location.sreg.startbit,p.location.sreg.subsetreg,tmpreg);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
tmpreg:=cg.getintregister(list,OS_INT);
|
||||||
|
hlcg.a_load_loc_reg(list,p.resultdef,osuinttype,p.location,tmpreg);
|
||||||
|
end;
|
||||||
|
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,truelabel);
|
||||||
|
cg.a_jmp_always(list,falselabel);
|
||||||
|
end;
|
||||||
LOC_SUBSETREF,LOC_CSUBSETREF:
|
LOC_SUBSETREF,LOC_CSUBSETREF:
|
||||||
begin
|
begin
|
||||||
tmpreg := cg.getintregister(list,OS_INT);
|
if (p.location.sref.bitindexreg=NR_NO) and (p.location.sref.bitlen=1) then
|
||||||
hlcg.a_load_loc_reg(list,p.resultdef,osuinttype,p.location,tmpreg);
|
begin
|
||||||
|
tmpreg:=cg.getintregister(list,OS_INT);
|
||||||
|
hlcg.a_load_ref_reg(list,u8inttype,osuinttype,p.location.sref.ref,tmpreg);
|
||||||
|
|
||||||
|
if target_info.endian=endian_big then
|
||||||
|
hlcg.a_op_const_reg_reg(list,OP_AND,osuinttype,1 shl (8-(p.location.sref.startbit+1)),tmpreg,tmpreg)
|
||||||
|
else
|
||||||
|
hlcg.a_op_const_reg_reg(list,OP_AND,osuinttype,1 shl p.location.sref.startbit,tmpreg,tmpreg);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
tmpreg:=cg.getintregister(list,OS_INT);
|
||||||
|
hlcg.a_load_loc_reg(list,p.resultdef,osuinttype,p.location,tmpreg);
|
||||||
|
end;
|
||||||
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,truelabel);
|
cg.a_cmp_const_reg_label(list,OS_INT,OC_NE,0,tmpreg,truelabel);
|
||||||
cg.a_jmp_always(list,falselabel);
|
cg.a_jmp_always(list,falselabel);
|
||||||
end;
|
end;
|
||||||
|
31
tests/webtbs/tw33417.pp
Normal file
31
tests/webtbs/tw33417.pp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
type
|
||||||
|
tflags = bitpacked record // Flags
|
||||||
|
bit0,bit1,bit2,bit3,bit4,bit5,bit6,bit7 : boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
gflags : tflags;
|
||||||
|
|
||||||
|
procedure p;
|
||||||
|
|
||||||
|
var
|
||||||
|
flags : tflags;
|
||||||
|
begin
|
||||||
|
flags:=gflags;
|
||||||
|
if flags.bit5 then
|
||||||
|
halt(1);
|
||||||
|
if gflags.bit5 then
|
||||||
|
halt(1);
|
||||||
|
if not flags.bit6 then
|
||||||
|
halt(1);
|
||||||
|
if not gflags.bit6 then
|
||||||
|
halt(1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
gflags.bit4:=false;
|
||||||
|
gflags.bit5:=false;
|
||||||
|
gflags.bit6:=true;
|
||||||
|
p;
|
||||||
|
writeln('ok');
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user