mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 01:39:27 +02:00
* Some fixes for r8515:
* fixed set add-nodes in case left and right are swapped (taddset4) * fixed "in" expressions with packed sets in case left is < setbase (now tested by tw8258b, which was missing a {$packset 1} directive) git-svn-id: trunk@8519 -
This commit is contained in:
parent
1fa32dffef
commit
89ed91509a
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -6499,6 +6499,7 @@ tests/test/cg/taddreal2.pp svneol=native#text/plain
|
||||
tests/test/cg/taddset.pp svneol=native#text/plain
|
||||
tests/test/cg/taddset2.pp svneol=native#text/plain
|
||||
tests/test/cg/taddset3.pp svneol=native#text/plain
|
||||
tests/test/cg/taddset4.pp svneol=native#text/plain
|
||||
tests/test/cg/tadint64.pp svneol=native#text/plain
|
||||
tests/test/cg/tassign1.pp svneol=native#text/plain
|
||||
tests/test/cg/tassign2.pp svneol=native#text/plain
|
||||
|
@ -269,7 +269,10 @@ interface
|
||||
location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,false);
|
||||
|
||||
set_result_location_reg;
|
||||
setbase:=tsetdef(left.resultdef).setbase;
|
||||
if (left.resultdef.typ=setdef) then
|
||||
setbase:=tsetdef(left.resultdef).setbase
|
||||
else
|
||||
setbase:=tsetdef(right.resultdef).setbase;
|
||||
|
||||
case nodetype of
|
||||
addn :
|
||||
|
@ -418,17 +418,22 @@ implementation
|
||||
else
|
||||
begin
|
||||
location_force_reg(current_asmdata.CurrAsmList, left.location, opsize, true);
|
||||
register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
|
||||
pleftreg := left.location.register;
|
||||
|
||||
if (opsize >= OS_S8) or { = if signed }
|
||||
((left.resultdef.typ=orddef) and (torddef(left.resultdef).high > tsetdef(right.resultdef).setmax)) or
|
||||
((left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax)) then
|
||||
((left.resultdef.typ=orddef) and
|
||||
((torddef(left.resultdef).low < int64(tsetdef(right.resultdef).setbase)) or
|
||||
(torddef(left.resultdef).high > int64(tsetdef(right.resultdef).setmax)))) or
|
||||
((left.resultdef.typ=enumdef) and
|
||||
((tenumdef(left.resultdef).min < tsetdef(right.resultdef).setbase) or
|
||||
(tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax))) then
|
||||
begin
|
||||
current_asmdata.getjumplabel(l);
|
||||
current_asmdata.getjumplabel(l2);
|
||||
needslabel := True;
|
||||
|
||||
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, left.location.size, OC_BE, tsetdef(right.resultdef).setmax, pleftreg, l);
|
||||
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, left.location.size, OC_BE, tsetdef(right.resultdef).setmax-tsetdef(right.resultdef).setbase, pleftreg, l);
|
||||
|
||||
cg.a_load_const_reg(current_asmdata.CurrAsmList, location.size, 0, location.register);
|
||||
cg.a_jmp_always(current_asmdata.CurrAsmList, l2);
|
||||
@ -436,8 +441,6 @@ implementation
|
||||
cg.a_label(current_asmdata.CurrAsmList, l);
|
||||
end;
|
||||
|
||||
register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
|
||||
pleftreg:=left.location.register;
|
||||
cg.a_bit_test_reg_loc_reg(current_asmdata.CurrAsmList,left.location.size,location.size,
|
||||
pleftreg,right.location,location.register);
|
||||
|
||||
|
@ -313,8 +313,8 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (Tordconstnode(left).value.signed and (Tordconstnode(left).value<0)) or
|
||||
(Tordconstnode(left).value.uvalue>Tsetdef(right.resultdef).setmax) then
|
||||
if (Tordconstnode(left).value<int64(tsetdef(right.resultdef).setbase)) or
|
||||
(Tordconstnode(left).value>int64(Tsetdef(right.resultdef).setmax)) then
|
||||
begin
|
||||
t:=cordconstnode.create(0, booltype, true);
|
||||
typecheckpass(t);
|
||||
|
@ -404,7 +404,10 @@ implementation
|
||||
if not(cmpop) then
|
||||
location.register := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
|
||||
setbase:=tsetdef(left.resultdef).setbase;
|
||||
if (left.resultdef.typ=setdef) then
|
||||
setbase:=tsetdef(left.resultdef).setbase
|
||||
else
|
||||
setbase:=tsetdef(right.resultdef).setbase;
|
||||
case nodetype of
|
||||
addn :
|
||||
begin
|
||||
|
@ -350,7 +350,10 @@ unit nx86add;
|
||||
extra_not:=false;
|
||||
all_member_optimization:=false;
|
||||
opsize:=int_cgsize(resultdef.size);
|
||||
setbase:=tsetdef(left.resultdef).setbase;
|
||||
if (left.resultdef.typ=setdef) then
|
||||
setbase:=tsetdef(left.resultdef).setbase
|
||||
else
|
||||
setbase:=tsetdef(right.resultdef).setbase;
|
||||
case nodetype of
|
||||
addn :
|
||||
begin
|
||||
|
@ -39,7 +39,7 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
globtype,systems,
|
||||
globtype,systems,constexp,
|
||||
verbose,globals,
|
||||
symconst,symdef,defutil,
|
||||
aasmbase,aasmtai,aasmdata,aasmcpu,
|
||||
@ -413,11 +413,16 @@ implementation
|
||||
else
|
||||
begin
|
||||
location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false);
|
||||
register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
|
||||
pleftreg:=left.location.register;
|
||||
|
||||
if (opsize >= OS_S8) or { = if signed }
|
||||
((left.resultdef.typ=orddef) and (torddef(left.resultdef).high.svalue > tsetdef(right.resultdef).setmax)) or
|
||||
((left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax)) then
|
||||
((left.resultdef.typ=orddef) and
|
||||
((torddef(left.resultdef).low < int64(tsetdef(right.resultdef).setbase)) or
|
||||
(torddef(left.resultdef).high > int64(tsetdef(right.resultdef).setmax)))) or
|
||||
((left.resultdef.typ=enumdef) and
|
||||
((tenumdef(left.resultdef).min < tsetdef(right.resultdef).setbase) or
|
||||
(tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax))) then
|
||||
begin
|
||||
|
||||
{ we have to check if the value is < 0 or > setmax }
|
||||
@ -426,14 +431,13 @@ implementation
|
||||
current_asmdata.getjumplabel(l2);
|
||||
|
||||
{ BE will be false for negative values }
|
||||
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_BE,tsetdef(right.resultdef).setmax,pleftreg,l);
|
||||
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_BE,tsetdef(right.resultdef).setmax-tsetdef(right.resultdef).setbase,pleftreg,l);
|
||||
{ reset carry flag }
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO));
|
||||
cg.a_jmp_always(current_asmdata.CurrAsmList,l2);
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList,l);
|
||||
|
||||
register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
|
||||
pleftreg:=left.location.register;
|
||||
case right.location.loc of
|
||||
LOC_REGISTER, LOC_CREGISTER :
|
||||
@ -451,8 +455,6 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
|
||||
pleftreg:=left.location.register;
|
||||
case right.location.loc of
|
||||
LOC_REGISTER, LOC_CREGISTER :
|
||||
emit_reg_reg(A_BT,S_L,pleftreg,right.location.register);
|
||||
|
29
tests/test/cg/taddset4.pp
Normal file
29
tests/test/cg/taddset4.pp
Normal file
@ -0,0 +1,29 @@
|
||||
type
|
||||
TCompilerIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
|
||||
TCompilerIntfFlags = set of TCompilerIntfFlag;
|
||||
|
||||
procedure t(l: longint);
|
||||
begin
|
||||
writeln(hexstr(l,8));
|
||||
{ exactly 3 bits must be set }
|
||||
l:=l and (l-1);
|
||||
if (l = 0) then
|
||||
halt(1);
|
||||
l:=l and (l-1);
|
||||
if (l = 0) then
|
||||
halt(2);
|
||||
l:=l and (l-1);
|
||||
if (l <> 0) then
|
||||
halt(3);
|
||||
end;
|
||||
|
||||
var
|
||||
b:boolean;
|
||||
begin
|
||||
b:=true;
|
||||
t(longint([
|
||||
TCompilerIntfFlag(ord(ifHasGuid)*ord(b)),
|
||||
TCompilerIntfFlag(ord(ifHasStrGUID)*ord(b)),
|
||||
TCompilerIntfFlag(ord(ifDispInterface)*ord(b))
|
||||
]));
|
||||
end.
|
@ -4,6 +4,7 @@ program SetTests;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$mode delphi}
|
||||
{$packset 1}
|
||||
{$ENDIF}
|
||||
|
||||
{$R+}
|
||||
|
Loading…
Reference in New Issue
Block a user