From 89ed91509ab4c8a7f892d43915e9ffa1afeba88a Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 16 Sep 2007 22:24:42 +0000 Subject: [PATCH] * 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 - --- .gitattributes | 1 + compiler/ncgadd.pas | 5 ++++- compiler/ncgset.pas | 13 ++++++++----- compiler/nset.pas | 4 ++-- compiler/ppcgen/ngppcadd.pas | 5 ++++- compiler/x86/nx86add.pas | 5 ++++- compiler/x86/nx86set.pas | 16 +++++++++------- tests/test/cg/taddset4.pp | 29 +++++++++++++++++++++++++++++ tests/webtbs/tw8258b.pp | 1 + 9 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 tests/test/cg/taddset4.pp diff --git a/.gitattributes b/.gitattributes index 0db2b9fdeb..35a1767fd6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/compiler/ncgadd.pas b/compiler/ncgadd.pas index 265e364b40..20139d30b6 100644 --- a/compiler/ncgadd.pas +++ b/compiler/ncgadd.pas @@ -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 : diff --git a/compiler/ncgset.pas b/compiler/ncgset.pas index d0734f6322..41f46effd4 100644 --- a/compiler/ncgset.pas +++ b/compiler/ncgset.pas @@ -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); diff --git a/compiler/nset.pas b/compiler/nset.pas index 6868ac1d26..60fe479b58 100644 --- a/compiler/nset.pas +++ b/compiler/nset.pas @@ -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).valueint64(Tsetdef(right.resultdef).setmax)) then begin t:=cordconstnode.create(0, booltype, true); typecheckpass(t); diff --git a/compiler/ppcgen/ngppcadd.pas b/compiler/ppcgen/ngppcadd.pas index f773e9275e..99d061a0ad 100644 --- a/compiler/ppcgen/ngppcadd.pas +++ b/compiler/ppcgen/ngppcadd.pas @@ -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 diff --git a/compiler/x86/nx86add.pas b/compiler/x86/nx86add.pas index ddc1531165..4728d62d0f 100644 --- a/compiler/x86/nx86add.pas +++ b/compiler/x86/nx86add.pas @@ -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 diff --git a/compiler/x86/nx86set.pas b/compiler/x86/nx86set.pas index a3d8c436ce..14866de91b 100644 --- a/compiler/x86/nx86set.pas +++ b/compiler/x86/nx86set.pas @@ -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); diff --git a/tests/test/cg/taddset4.pp b/tests/test/cg/taddset4.pp new file mode 100644 index 0000000000..47d515db1e --- /dev/null +++ b/tests/test/cg/taddset4.pp @@ -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. diff --git a/tests/webtbs/tw8258b.pp b/tests/webtbs/tw8258b.pp index 441bbc5e73..841a24e757 100644 --- a/tests/webtbs/tw8258b.pp +++ b/tests/webtbs/tw8258b.pp @@ -4,6 +4,7 @@ program SetTests; {$IFDEF FPC} {$mode delphi} + {$packset 1} {$ENDIF} {$R+}