浏览代码

* fixed generic in-code in case left = LOC_JUMP
* fixed generic and x86 in-code in case genjumps=true and
complexity(right)>complexity(left) (not sure if possible
in practice currently, but better safe than sorry)

git-svn-id: trunk@7912 -

Jonas Maebe 18 年之前
父节点
当前提交
e23a8655e8
共有 3 个文件被更改,包括 56 次插入7 次删除
  1. 33 6
      compiler/ncgset.pas
  2. 5 1
      compiler/x86/nx86set.pas
  3. 18 0
      tests/test/cg/tin.pp

+ 33 - 6
compiler/ncgset.pas

@@ -207,15 +207,16 @@ implementation
        var
          adjustment : aint;
          l, l2      : tasmlabel;
-         href : treference;
-         hr,hr2,
+         otl, ofl   : tasmlabel;
+         hr,
          pleftreg   : tregister;
          setparts   : Tsetparts;
          opsize     : tcgsize;
          uopsize    : tcgsize;
          orgopsize  : tcgsize;
          genjumps,
-         use_small  : boolean;
+         use_small,
+         isjump     : boolean;
          i,numparts : byte;
          needslabel : Boolean;
        begin
@@ -232,10 +233,36 @@ implementation
            opsize := uopsize;
          needslabel := false;
 
-         { calculate both operators }
-         { the complex one first }
-         firstcomplex(self);
+         isjump:=false;
+         if (left.expectloc=LOC_JUMP) then
+           begin
+             otl:=current_procinfo.CurrTrueLabel;
+             current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
+             ofl:=current_procinfo.CurrFalseLabel;
+             current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
+             isjump:=true;
+           end
+         else if not genjumps then
+           { calculate both operators }
+           { the complex one first }
+           { only if left will not be a LOC_JUMP, to keep complexity in the }
+           { code generator down. This almost never happens anyway, only in }
+           { case like "if ((a in someset) in someboolset) then" etc        }
+           { also not in case of genjumps, because then we don't secondpass }
+           { right at all (so we have to make sure that "right" really is   }
+           { "right" and not "swapped left" in that case)                   }
+           firstcomplex(self);
+
          secondpass(left);
+         if isjump then
+           begin
+             location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
+             current_procinfo.CurrTrueLabel:=otl;
+             current_procinfo.CurrFalseLabel:=ofl;
+           end
+         else if (left.location.loc=LOC_JUMP) then
+           internalerror(2007070101);
+
          { Only process the right if we are not generating jumps }
          if not genjumps then
            secondpass(right);

+ 5 - 1
compiler/x86/nx86set.pas

@@ -170,7 +170,11 @@ implementation
                    analizeset(tsetconstnode(right).value_set,use_small);
          { calculate both operators }
          { the complex one first }
-         firstcomplex(self);
+         { not in case of genjumps, because then we don't secondpass    }
+         { right at all (so we have to make sure that "right" really is }
+         { "right" and not "swapped left" in that case)                 }
+         if not(genjumps) then
+           firstcomplex(self);
          secondpass(left);
          { Only process the right if we are not generating jumps }
          if not genjumps then

+ 18 - 0
tests/test/cg/tin.pp

@@ -298,6 +298,7 @@ var
    var
      op1 : tnormalset;
      op2 : tnormalset;
+     bs  : set of boolean;
      op  : tbigenum;
      passed : boolean;
    begin
@@ -347,6 +348,23 @@ var
        passed:=false;
 
      checkpassed(passed);
+
+
+     { LEFT : LOC_JUMP                            }
+     { RIGHT : LOC_REGISTER,LOC_CREGISTER         }
+     bs:=[false,true];
+     op:=A_MOVE;
+     passed:=true;
+     if not(not(op in [A_BFSET,A_MOVE,A_ASL..A_BCC]) in bs) then
+       passed := false;
+     if not((op in [A_BFSET,A_MOVE,A_ASL..A_BCC]) in bs) then
+       passed := false;
+
+     bs:=[false];
+     if ((op in [A_BFSET,A_MOVE,A_ASL..A_BCC]) in bs) then
+       passed := false;
+
+     checkpassed(passed);
    end;
 
    { WITH JUMP TABLE }