Browse Source

+ support for extra packing of sets whose lower element number
is <> 0 (Delphi compatible now, + various tests)
+ support for enums and sets in is_in_limit()
* fixed converting smallset expressions to varsets
* improved choosing an appropriate common set type when mixing
set types in an expression
- removed no longer used normalset code from nadd.pas
- disabled large set (>256 elements) support for now, because
they are not yet supported entirely throughout the compiler
and this causes errors at run time in several situations

git-svn-id: trunk@8515 -

Jonas Maebe 18 years ago
parent
commit
0040eecf9f

+ 7 - 0
.gitattributes

@@ -6498,6 +6498,7 @@ tests/test/cg/taddreal1.pp svneol=native#text/plain
 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/tadint64.pp svneol=native#text/plain
 tests/test/cg/tassign1.pp svneol=native#text/plain
 tests/test/cg/tassign2.pp svneol=native#text/plain
@@ -7034,12 +7035,17 @@ tests/test/trtti4.pp svneol=native#text/plain
 tests/test/trtti5.pp svneol=native#text/plain
 tests/test/tset1.pp svneol=native#text/plain
 tests/test/tset2.pp svneol=native#text/plain
+tests/test/tset2a.pp svneol=native#text/plain
+tests/test/tset2b.pp svneol=native#text/plain
+tests/test/tset2c.pp svneol=native#text/plain
+tests/test/tset2d.pp svneol=native#text/plain
 tests/test/tset3.pp svneol=native#text/plain
 tests/test/tset4.pp svneol=native#text/plain
 tests/test/tset5.pp svneol=native#text/plain
 tests/test/tset5a.pp svneol=native#text/plain
 tests/test/tset6.pp svneol=native#text/plain
 tests/test/tset7.pp svneol=native#text/plain
+tests/test/tsetsize.pp svneol=native#text/plain
 tests/test/tstack.pp svneol=native#text/plain
 tests/test/tstprocv.pp svneol=native#text/plain
 tests/test/tstring1.pp svneol=native#text/plain
@@ -8345,6 +8351,7 @@ tests/webtbs/tw8229.pp svneol=native#text/plain
 tests/webtbs/tw8232.pp svneol=native#text/plain
 tests/webtbs/tw8258.pp svneol=native#text/plain
 tests/webtbs/tw8258a.pp svneol=native#text/plain
+tests/webtbs/tw8258b.pp svneol=native#text/plain
 tests/webtbs/tw8264.pp svneol=native#text/plain
 tests/webtbs/tw8282.pp svneol=native#text/plain
 tests/webtbs/tw8283.pp svneol=native#text/plain

+ 13 - 3
compiler/defutil.pas

@@ -450,13 +450,23 @@ implementation
     function is_in_limit(def_from,def_to : tdef) : boolean;
 
       begin
-         if (def_from.typ <> orddef) or (def_to.typ <> orddef) then
+         if (def_from.typ<>def_to.typ) or
+            not(def_from.typ in [orddef,enumdef,setdef]) then
            begin
              is_in_limit := false;
              exit;
            end;
-         is_in_limit:=(torddef(def_from).low>=torddef(def_to).low) and
-                      (torddef(def_from).high<=torddef(def_to).high);
+         case def_from.typ of
+           orddef:
+             is_in_limit:=(torddef(def_from).low>=torddef(def_to).low) and
+                          (torddef(def_from).high<=torddef(def_to).high);
+           enumdef:
+             is_in_limit:=(tenumdef(def_from).min>=tenumdef(def_to).min) and
+                          (tenumdef(def_from).max<=tenumdef(def_to).max);
+           setdef:
+             is_in_limit:=(tsetdef(def_from).setbase>=tsetdef(def_to).setbase) and
+                          (tsetdef(def_from).setmax<=tsetdef(def_to).setmax);
+         end;
       end;
 
     { true, if p points to an open array def }

+ 114 - 174
compiler/nadd.pas

@@ -658,7 +658,7 @@ implementation
                to right as the other way is checked in the typeconv }
              if (tsetdef(right.resultdef).settype=smallset) and
                 (tsetdef(left.resultdef).settype<>smallset) then
-               right.resultdef:=tsetdef.create(tsetdef(right.resultdef).elementdef,255);
+               right.resultdef:=tsetdef.create(tsetdef(right.resultdef).elementdef,0,255);
              { check base types }
              inserttypeconv(left,right.resultdef);
 
@@ -735,17 +735,19 @@ implementation
 
     function taddnode.pass_typecheck_internal:tnode;
       var
-        hp      : tnode;
-        rd,ld   : tdef;
-        hsym    : tfieldvarsym;
-        i       : longint;
-        strtype : tstringtype;
-        b       : boolean;
-        lt,rt   : tnodetype;
-        ot      : tnodetype;
+        hp          : tnode;
+        rd,ld,nd    : tdef;
+        hsym        : tfieldvarsym;
+        i           : longint;
+        llow,lhigh,
+        rlow,rhigh  : tconstexprint;
+        strtype     : tstringtype;
+        b           : boolean;
+        lt,rt       : tnodetype;
+        ot          : tnodetype;
 {$ifdef state_tracking}
-        factval : Tnode;
-        change  : boolean;
+        factval     : Tnode;
+        change      : boolean;
 {$endif}
 
       begin
@@ -1198,30 +1200,72 @@ implementation
                  end
                else
                  CGMessage(type_e_mismatch);
-               { ranges require normsets on big endian system }
-               if (target_info.endian=endian_big) and
-                  (tsetdef(ld).size<>32) and
-                  (rt=setelementn) and
-                  assigned(tsetelementnode(right).right) then
-                begin
-                  { generate a temporary normset def, it'll be destroyed
-                    when the symtable is unloaded }
-                  inserttypeconv(left,tsetdef.create(tsetdef(ld).elementdef,255));
-                end;
              end
             else
              begin
                if not(nodetype in [addn,subn,symdifn,muln,equaln,unequaln,lten,gten]) then
                 CGMessage(type_e_set_operation_unknown);
-               { make operands the same setdef, if right is a normalset or varset then
-                 force the left side to be the same. General fallback also for non-set nodes
-                 is to convert right to a set }
+               { Make operands the same setdef. If one's elementtype fits   }
+               { entirely inside the other's, pick the one with the largest }
+               { range.  Otherwise create a new setdef with a range which   }
+               { can contain both.                                          }
                if not(equal_defs(ld,rd)) then
                 begin
-                  if is_varset(rd) then
+                  { note: ld cannot be an empty set with elementdef=nil in }
+                  { case right is not a set, arrayconstructor_to_set takes }
+                  { care of that                                           }
+                  
+                  { 1: rd is a set with an assigned elementdef, and ld is    }
+                  {    either an empty set without elementdef or a set whose }
+                  {    elementdef fits in rd's elementdef -> convert to rd   }
+                  if ((rd.typ=setdef) and
+                      assigned(tsetdef(rd).elementdef) and
+                      (not assigned(tsetdef(ld).elementdef) or
+                       is_in_limit(ld,rd))) then
                     inserttypeconv(left,right.resultdef)
+                  { 2: rd is either an empty set without elementdef or a set }
+                  {    whose elementdef fits in ld's elementdef, or a set    }
+                  {    element whose def fits in ld's elementdef -> convert  }
+                  {    to ld. ld's elementdef can't be nil here, is caught   }
+                  {    previous case and "note:" above                       }
+                  else if ((rd.typ=setdef) and
+                           (not assigned(tsetdef(rd).elementdef) or
+                            is_in_limit(rd,ld))) or
+                          ((rd.typ<>setdef) and
+                           is_in_limit(rd,tsetdef(ld).elementdef)) then
+                    inserttypeconv(right,left.resultdef)
+                  { 3: otherwise create setdef which encompasses both, taking }
+                  {    into account empty sets without elementdef             }
                   else
-                    inserttypeconv(right,left.resultdef);
+                    begin
+                      if assigned(tsetdef(ld).elementdef) then
+                        begin
+                          llow:=tsetdef(ld).setbase;
+                          lhigh:=tsetdef(ld).setmax;
+                        end;
+                      if (rd.typ=setdef) then
+                        if assigned(tsetdef(rd).elementdef) then
+                          begin
+                            rlow:=tsetdef(rd).setbase;
+                            rhigh:=tsetdef(rd).setmax;
+                          end
+                        else
+                          begin
+                            { ld's elementdef must have been valid }
+                            rlow:=llow;
+                            rhigh:=lhigh;
+                          end
+                      else
+                        getrange(rd,rlow,rhigh);
+                      if not assigned(tsetdef(ld).elementdef) then
+                        begin
+                          llow:=rlow;
+                          lhigh:=rhigh;
+                        end;
+                      nd:=tsetdef.create(tsetdef(ld).elementdef,min(llow,rlow),max(lhigh,rhigh));
+                      inserttypeconv(left,nd);
+                      inserttypeconv(right,nd);
+                    end;
                 end;
             end;
           end
@@ -1878,8 +1922,6 @@ implementation
       var
         procname: string[31];
         tempn: tnode;
-        paras: tcallparanode;
-        srsym: ttypesym;
         newstatement : tstatementnode;
         temp    : ttempcreatenode;
       begin
@@ -1927,10 +1969,15 @@ implementation
                       temp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,true);
                       addstatement(newstatement,temp);
 
+                      { adjust for set base }
+                      tsetelementnode(right).left:=caddnode.create(subn,
+                        ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),
+                        cordconstnode.create(tsetdef(resultdef).setbase,sinttype,false));
+
                       addstatement(newstatement,ccallnode.createintern('fpc_varset_create_element',
                         ccallparanode.create(ctemprefnode.create(temp),
                         ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
-                        ccallparanode.create(ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),nil))))
+                        ccallparanode.create(tsetelementnode(right).left,nil))))
                       );
 
                       { the last statement should return the value as
@@ -1952,15 +1999,26 @@ implementation
                           temp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,true);
                           addstatement(newstatement,temp);
 
+                          { adjust for set base }
+                          tsetelementnode(right).left:=caddnode.create(subn,
+                            ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),
+                            cordconstnode.create(tsetdef(resultdef).setbase,sinttype,false));
+                           
                           { add a range or a single element? }
                           if assigned(tsetelementnode(right).right) then
-                            addstatement(newstatement,ccallnode.createintern('fpc_varset_set_range',
-                              ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
-                              ccallparanode.create(ctypeconvnode.create_internal(tsetelementnode(right).right,sinttype),
-                              ccallparanode.create(ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),
-                              ccallparanode.create(ctemprefnode.create(temp),
-                              ccallparanode.create(left,nil))))))
-                            )
+                            begin
+                              { adjust for set base }
+                              tsetelementnode(right).right:=caddnode.create(subn,
+                                ctypeconvnode.create_internal(tsetelementnode(right).right,sinttype),
+                                cordconstnode.create(tsetdef(resultdef).setbase,sinttype,false));
+                              addstatement(newstatement,ccallnode.createintern('fpc_varset_set_range',
+                                ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
+                                ccallparanode.create(tsetelementnode(right).right,
+                                ccallparanode.create(tsetelementnode(right).left,
+                                ccallparanode.create(ctemprefnode.create(temp),
+                                ccallparanode.create(left,nil))))))
+                              );
+                            end
                           else
                             addstatement(newstatement,ccallnode.createintern('fpc_varset_set',
                               ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
@@ -1994,136 +2052,7 @@ implementation
             end;
           end
         else
-          begin
-            { get the sym that represents the fpc_normal_set type }
-            srsym:=search_system_type('FPC_NORMAL_SET');
-            case nodetype of
-              equaln,unequaln,lten,gten:
-                begin
-                  case nodetype of
-                    equaln,unequaln:
-                      procname := 'fpc_set_comp_sets';
-                    lten,gten:
-                      begin
-                        procname := 'fpc_set_contains_sets';
-                        { (left >= right) = (right <= left) }
-                        if nodetype = gten then
-                          begin
-                            tempn := left;
-                            left := right;
-                            right := tempn;
-                          end;
-                       end;
-                   end;
-                   { convert the arguments (explicitely) to fpc_normal_set's }
-                   left := ctypeconvnode.create_internal(left,srsym.typedef);
-                   right := ctypeconvnode.create_internal(right,srsym.typedef);
-                   result := ccallnode.createintern(procname,ccallparanode.create(right,
-                     ccallparanode.create(left,nil)));
-                   { left and right are reused as parameters }
-                   left := nil;
-                   right := nil;
-                   { for an unequaln, we have to negate the result of comp_sets }
-                   if nodetype = unequaln then
-                     result := cnotnode.create(result);
-                end;
-              addn:
-                begin
-                  { optimize first loading of a set }
-                  if (right.nodetype=setelementn) and
-                     not(assigned(tsetelementnode(right).right)) and
-                     is_emptyset(left) then
-                    begin
-                      { type cast the value to pass as argument to a byte, }
-                      { since that's what the helper expects               }
-                      tsetelementnode(right).left :=
-                        ctypeconvnode.create_internal(tsetelementnode(right).left,u8inttype);
-                      { set the resultdef to the actual one (otherwise it's }
-                      { "fpc_normal_set")                                    }
-                      result := ccallnode.createinternres('fpc_set_create_element',
-                        ccallparanode.create(tsetelementnode(right).left,nil),
-                        resultdef);
-                      { reused }
-                      tsetelementnode(right).left := nil;
-                    end
-                  else
-                    begin
-                      if right.nodetype=setelementn then
-                       begin
-                         { convert the arguments to bytes, since that's what }
-                         { the helper expects                               }
-                         tsetelementnode(right).left :=
-                           ctypeconvnode.create_internal(tsetelementnode(right).left,
-                           u8inttype);
-
-                         { convert the original set (explicitely) to an   }
-                         { fpc_normal_set so we can pass it to the helper }
-                         left := ctypeconvnode.create_internal(left,srsym.typedef);
-
-                         { add a range or a single element? }
-                         if assigned(tsetelementnode(right).right) then
-                           begin
-                             tsetelementnode(right).right :=
-                               ctypeconvnode.create_internal(tsetelementnode(right).right,
-                               u8inttype);
-
-                             { create the call }
-                             result := ccallnode.createinternres('fpc_set_set_range',
-                               ccallparanode.create(tsetelementnode(right).right,
-                               ccallparanode.create(tsetelementnode(right).left,
-                               ccallparanode.create(left,nil))),resultdef);
-                           end
-                         else
-                           begin
-                             result := ccallnode.createinternres('fpc_set_set_byte',
-                               ccallparanode.create(tsetelementnode(right).left,
-                               ccallparanode.create(left,nil)),resultdef);
-                           end;
-                         { remove reused parts from original node }
-                         tsetelementnode(right).right := nil;
-                         tsetelementnode(right).left := nil;
-                         left := nil;
-                       end
-                      else
-                       begin
-                         { add two sets }
-
-                         { convert the sets to fpc_normal_set's }
-                         result := ccallnode.createinternres('fpc_set_add_sets',
-                           ccallparanode.create(
-                             ctypeconvnode.create_explicit(right,srsym.typedef),
-                           ccallparanode.create(
-                             ctypeconvnode.create_internal(left,srsym.typedef),nil)),resultdef);
-                         { remove reused parts from original node }
-                         left := nil;
-                         right := nil;
-                       end;
-                    end
-                end;
-              subn,symdifn,muln:
-                begin
-                  { convert the sets to fpc_normal_set's }
-                  paras := ccallparanode.create(ctypeconvnode.create_internal(right,srsym.typedef),
-                    ccallparanode.create(ctypeconvnode.create_internal(left,srsym.typedef),nil));
-                  case nodetype of
-                    subn:
-                      result := ccallnode.createinternres('fpc_set_sub_sets',
-                        paras,resultdef);
-                    symdifn:
-                      result := ccallnode.createinternres('fpc_set_symdif_sets',
-                        paras,resultdef);
-                    muln:
-                      result := ccallnode.createinternres('fpc_set_mul_sets',
-                        paras,resultdef);
-                  end;
-                  { remove reused parts from original node }
-                  left := nil;
-                  right := nil;
-                end;
-              else
-                internalerror(200108311);
-            end;
-          end;
+          internalerror(2007091601);
       end;
 
 
@@ -2543,19 +2472,30 @@ implementation
                          temp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,true);
                          addstatement(newstatement,temp);
 
+                         { adjust for set base }
+                         tsetelementnode(right).left:=caddnode.create(subn,
+                           ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),
+                           cordconstnode.create(tsetdef(resultdef).setbase,sinttype,false));
+
                          { add a range or a single element? }
                          if assigned(tsetelementnode(right).right) then
-                           addstatement(newstatement,ccallnode.createintern('fpc_varset_set_range',
-                             ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
-                             ccallparanode.create(ctypeconvnode.create_internal(tsetelementnode(right).right,sinttype),
-                             ccallparanode.create(ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),
-                             ccallparanode.create(ctemprefnode.create(temp),
-                             ccallparanode.create(left,nil))))))
-                           )
+                           begin
+                             { adjust for set base }
+                             tsetelementnode(right).right:=caddnode.create(subn,
+                               ctypeconvnode.create_internal(tsetelementnode(right).right,sinttype),
+                               cordconstnode.create(tsetdef(resultdef).setbase,sinttype,false));
+                             addstatement(newstatement,ccallnode.createintern('fpc_varset_set_range',
+                               ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
+                               ccallparanode.create(tsetelementnode(right).right,
+                               ccallparanode.create(tsetelementnode(right).left,
+                               ccallparanode.create(ctemprefnode.create(temp),
+                               ccallparanode.create(left,nil))))))
+                             )
+                           end
                          else
                            addstatement(newstatement,ccallnode.createintern('fpc_varset_set',
                              ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
-                             ccallparanode.create(ctypeconvnode.create_internal(tsetelementnode(right).left,sinttype),
+                             ccallparanode.create(tsetelementnode(right).left,
                              ccallparanode.create(ctemprefnode.create(temp),
                              ccallparanode.create(left,nil)))))
                            );

+ 9 - 5
compiler/ncgadd.pas

@@ -245,10 +245,12 @@ interface
 
     procedure tcgaddnode.second_addsmallset;
       var
-        cgop   : TOpCg;
         tmpreg : tregister;
-        mask   : aint;
-        opdone : boolean;
+        mask,
+        setbase : aint;
+        
+        cgop    : TOpCg;
+        opdone  : boolean;
       begin
         opdone := false;
 
@@ -267,6 +269,7 @@ interface
           location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,false);
 
         set_result_location_reg;
+        setbase:=tsetdef(left.resultdef).setbase;
 
         case nodetype of
           addn :
@@ -280,9 +283,9 @@ interface
                   if (right.location.loc = LOC_CONSTANT) then
                     begin
                       if (target_info.endian=endian_big) then
-                        mask:=aint((aword(1) shl (resultdef.size*8-1)) shr aword(right.location.value))
+                        mask:=aint((aword(1) shl (resultdef.size*8-1)) shr aword(right.location.value-setbase))
                       else
-                        mask:=aint(1 shl right.location.value);
+                        mask:=aint(1 shl (right.location.value-setbase));
                       cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_OR,location.size,
                         mask,left.location.register,location.register);
                     end
@@ -301,6 +304,7 @@ interface
                       tmpreg := cg.getintregister(current_asmdata.CurrAsmList,location.size);
                       cg.a_load_const_reg(current_asmdata.CurrAsmList,location.size,mask,tmpreg);
                       location_force_reg(current_asmdata.CurrAsmList,right.location,location.size,true);
+                      register_maybe_adjust_setbase(current_asmdata.CurrAsmList,right.location,setbase);
                       cg.a_op_reg_reg(current_asmdata.CurrAsmList,cgop,location.size,
                         right.location.register,tmpreg);
                       if left.location.loc <> LOC_CONSTANT then

+ 3 - 1
compiler/ncgcon.pas

@@ -508,12 +508,14 @@ implementation
       var
          hp1         : tai;
          lastlabel   : tasmlabel;
-         i           : longint;
+         i, diff     : longint;
          neededtyp   : taiconst_type;
       type
          setbytes=array[0..31] of byte;
          Psetbytes=^setbytes;
       begin
+        adjustforsetbase;
+
         { small sets are loaded as constants }
         if not(is_varset(resultdef)) then
          begin

+ 2 - 1
compiler/ncginl.pas

@@ -521,11 +521,12 @@ implementation
           if elepara.location.loc=LOC_CONSTANT then
             begin
               cg.a_bit_set_const_loc(current_asmdata.CurrAsmList,(inlinenumber=in_include_x_y),
-                elepara.location.value,setpara.location);
+                elepara.location.value-tsetdef(setpara.resultdef).setbase,setpara.location);
             end
           else
             begin
               location_force_reg(current_asmdata.CurrAsmList,elepara.location,OS_INT,true);
+              register_maybe_adjust_setbase(current_asmdata.CurrAsmList,elepara.location,tsetdef(setpara.resultdef).setbase);
               cg.a_bit_set_reg_loc(current_asmdata.CurrAsmList,(inlinenumber=in_include_x_y),
                 elepara.location.size,elepara.location.register,setpara.location);
             end;

+ 13 - 7
compiler/ncgset.pas

@@ -205,7 +205,8 @@ implementation
 
     procedure tcginnode.pass_generate_code;
        var
-         adjustment : aint;
+         adjustment,
+         setbase    : aint;
          l, l2      : tasmlabel;
          otl, ofl   : tasmlabel;
          hr,
@@ -273,6 +274,7 @@ implementation
          if nf_swapped in flags then
           swapleftright;
 
+         setbase:=tsetdef(right.resultdef).setbase;
          if genjumps then
           begin
             { location is always LOC_JUMP }
@@ -361,12 +363,13 @@ implementation
                if left.location.loc=LOC_CONSTANT then
                 begin
                   cg.a_bit_test_const_loc_reg(current_asmdata.CurrAsmList,location.size,
-                    left.location.value,right.location,
+                    left.location.value-setbase,right.location,
                     location.register);
                 end
                else
                 begin
                   location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
+                  register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
                   cg.a_bit_test_reg_loc_reg(current_asmdata.CurrAsmList,left.location.size,
                     location.size,left.location.register,right.location,location.register);
                 end;
@@ -384,11 +387,12 @@ implementation
 
                   { load left in register }
                   location_force_reg(current_asmdata.CurrAsmList,left.location,location.size,true);
+                  register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
                   location_force_reg(current_asmdata.CurrAsmList,right.location,opsize,true);
                   { emit bit test operation }
                   cg.a_bit_test_reg_reg_reg(current_asmdata.CurrAsmList,
                     left.location.size,right.location.size,location.size,
-                    left.location.register, right.location.register,location.register);
+                    left.location.register,right.location.register,location.register);
 
                   { now zero the result if left > nr_of_bits_in_right_register }
                   hr := cg.getintregister(current_asmdata.CurrAsmList,location.size);
@@ -400,15 +404,15 @@ implementation
                   { if left > tcgsize2size[opsize]*8-1, then result := 0 else result := result of bit test }
                   cg.a_op_reg_reg(current_asmdata.CurrAsmList, OP_AND, location.size, hr, location.register);
                 end { of right.location.loc=LOC_CONSTANT }
-               { do search in a normal set which could have >32 elementsm
+               { do search in a normal set which could have >32 elements
                  but also used if the left side contains higher values > 32 }
                else if (left.location.loc=LOC_CONSTANT) then
                 begin
-                  if (left.location.value < 0) or ((left.location.value shr 3) >= right.resultdef.size) then
+                  if (left.location.value < setbase) or (((left.location.value-setbase) shr 3) >= right.resultdef.size) then
                     {should be caught earlier }
                     internalerror(2007020402);
 
-                  cg.a_bit_test_const_loc_reg(current_asmdata.CurrAsmList,location.size,left.location.value,
+                  cg.a_bit_test_const_loc_reg(current_asmdata.CurrAsmList,location.size,left.location.value-setbase,
                     right.location,location.register);
                 end
                else
@@ -432,8 +436,10 @@ 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,
-                    left.location.register,right.location,location.register);
+                    pleftreg,right.location,location.register);
 
                   if needslabel then
                     cg.a_label(current_asmdata.CurrAsmList, l2);

+ 27 - 0
compiler/ncgutil.pas

@@ -65,6 +65,7 @@ interface
     procedure location_force_mem(list:TAsmList;var l:tlocation);
     procedure location_force_mmregscalar(list:TAsmList;var l: tlocation;maybeconst:boolean);
     procedure location_force_mmreg(list:TAsmList;var l: tlocation;maybeconst:boolean);
+    procedure register_maybe_adjust_setbase(list: TAsmList; var l: tlocation; setbase: aint);
 
     { Retrieve the location of the data pointed to in location l, when the location is
       a register it is expected to contain the address of the data }
@@ -725,6 +726,32 @@ implementation
       end;
 
 
+    procedure register_maybe_adjust_setbase(list: TAsmList; var l: tlocation; setbase: aint);
+      var
+        tmpreg: tregister;
+      begin
+        if (setbase<>0) then
+          begin
+            if not(l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+              internalerror(2007091502);
+            { subtract the setbase }
+            case l.loc of
+              LOC_CREGISTER:
+                begin
+                  tmpreg := cg.getintregister(list,l.size);
+                  cg.a_op_const_reg_reg(list,OP_SUB,l.size,setbase,l.register,tmpreg);
+                  l.loc:=LOC_REGISTER;
+                  l.register:=tmpreg;
+                end;
+              LOC_REGISTER:
+                begin
+                  cg.a_op_const_reg(list,OP_SUB,l.size,setbase,l.register);
+                end;
+            end;
+          end;
+      end;
+
+
     procedure location_force_mmreg(list:TAsmList;var l: tlocation;maybeconst:boolean);
       var
         reg : tregister;

+ 58 - 12
compiler/ncnv.pas

@@ -296,18 +296,23 @@ implementation
 
         procedure update_constsethi(def:tdef);
           begin
-            if ((def.typ=orddef) and
-                (torddef(def).high>=constsethi)) then
+            if (def.typ=orddef) and
+               ((torddef(def).high>=constsethi) or
+                (torddef(def).low <=constsetlo)) then
               begin
                 if torddef(def).ordtype=uwidechar then
                   begin
                     constsethi:=255;
+                    constsetlo:=0;
                     if hdef=nil then
                       hdef:=def;
                   end
                 else
                   begin
-                    constsethi:=torddef(def).high;
+                    if (torddef(def).high>=constsethi) then
+                      constsethi:=torddef(def).high;
+                    if (torddef(def).low<=constsetlo) then
+                      constsetlo:=torddef(def).low;
                     if hdef=nil then
                       begin
                          if (constsethi>255) or
@@ -318,14 +323,20 @@ implementation
                       end;
                     if constsethi>255 then
                       constsethi:=255;
+                    if constsetlo<0 then
+                      constsetlo:=0;
                   end;
               end
-            else if ((def.typ=enumdef) and
-                    (tenumdef(def).max>=constsethi)) then
+            else if (def.typ=enumdef) and
+                    ((tenumdef(def).max>=constsethi) or
+                     (tenumdef(def).min<=constsetlo)) then
               begin
                  if hdef=nil then
                    hdef:=def;
-                 constsethi:=tenumdef(def).max;
+                 if (tenumdef(def).max>=constsethi) then
+                   constsethi:=tenumdef(def).max;
+                 if (tenumdef(def).min<=constsetlo) then
+                   constsetlo:=tenumdef(def).min;
               end;
           end;
 
@@ -352,7 +363,11 @@ implementation
         new(constset);
         constset^:=[];
         hdef:=nil;
-        constsetlo:=0;
+        { make sure to set constsetlo correctly for empty sets }
+        if assigned(tarrayconstructornode(p).left) then
+          constsetlo:=high(aint)
+        else
+          constsetlo:=0;
         constsethi:=0;
         constp:=csetconstnode.create(nil,hdef);
         constp.value_set:=constset;
@@ -536,7 +551,7 @@ implementation
            p.free;
          end;
         { set the initial set type }
-        constp.resultdef:=tsetdef.create(hdef,constsethi.svalue);
+        constp.resultdef:=tsetdef.create(hdef,constsetlo.svalue,constsethi.svalue);
         { determine the resultdef for the tree }
         typecheckpass(buildp);
         { set the new tree }
@@ -2361,9 +2376,8 @@ implementation
 
     function ttypeconvnode.first_set_to_set : tnode;
       var
-        srsym: ttypesym;
         newstatement : tstatementnode;
-        temp    : ttempcreatenode;
+        temp         : ttempcreatenode;
       begin
         { in theory, we should do range checking here,
           but Delphi doesn't do it either (FK) }
@@ -2376,21 +2390,53 @@ implementation
         { equal sets for the code generator? }
         else if (left.resultdef.size=resultdef.size) and
           (tsetdef(left.resultdef).setbase=tsetdef(resultdef).setbase) then
+          {$warning This causes wrong (but Delphi-compatible) results for disjoint subsets}
+          { e.g., this prints true because of this:
+              var
+                sa: set of 1..2;
+                sb: set of 5..6;
+                b: byte;
+              begin
+                b:=1;
+                sa:=[1..2];
+                sb:=sa;
+                writeln(b in sb);
+              end.
+          }
           result:=left
         else
         // if is_varset(resultdef) then
           begin
             result:=internalstatements(newstatement);
 
+            { in case left is a smallset expression, it can be an addn or so. }
+            { fpc_varset_load expects a formal const parameter, which doesn't }
+            { accept set addn's -> assign to a temp first and pass the temp   }
+            if not(left.expectloc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+              begin
+                temp:=ctempcreatenode.create(left.resultdef,left.resultdef.size,tt_persistent,false);
+                addstatement(newstatement,temp);
+                { temp := left }
+                addstatement(newstatement,cassignmentnode.create(
+                  ctemprefnode.create(temp),left));
+                addstatement(newstatement,ctempdeletenode.create_normal_temp(temp));
+                addstatement(newstatement,ctemprefnode.create(temp));
+                left:=result;
+                firstpass(left);
+                { recreate the result's internalstatements list }
+                result:=internalstatements(newstatement);
+              end;
+
             { create temp for result }
             temp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,true);
-                          addstatement(newstatement,temp);
+            addstatement(newstatement,temp);
 
             addstatement(newstatement,ccallnode.createintern('fpc_varset_load',
+              ccallparanode.create(cordconstnode.create(tsetdef(left.resultdef).setbase div 8 - tsetdef(resultdef).setbase div 8,sinttype,false),
               ccallparanode.create(cordconstnode.create(resultdef.size,sinttype,false),
               ccallparanode.create(ctemprefnode.create(temp),
               ccallparanode.create(cordconstnode.create(left.resultdef.size,sinttype,false),
-              ccallparanode.create(left,nil)))))
+              ccallparanode.create(left,nil))))))
             );
             addstatement(newstatement,ctempdeletenode.create_normal_temp(temp));
             addstatement(newstatement,ctemprefnode.create(temp));

+ 32 - 0
compiler/ncon.pas

@@ -148,6 +148,7 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderefimpl;override;
           procedure derefimpl;override;
+          procedure adjustforsetbase;
           function dogetcopy : tnode;override;
           function pass_1 : tnode;override;
           function pass_typecheck:tnode;override;
@@ -999,6 +1000,37 @@ implementation
       end;
 
 
+    procedure tsetconstnode.adjustforsetbase;
+      type
+         setbytes = array[0..31] of byte;
+         Psetbytes = ^setbytes;
+      var
+        i, diff: longint;
+      begin
+        { Internally, the compiler stores all sets with setbase 0, so we have }
+        { to convert the set to its actual format in case setbase<>0 when     }
+        { writing it out                                                      }
+        if (tsetdef(resultdef).setbase<>0) then
+          begin
+            if (tsetdef(resultdef).setbase and 7)<>0 then
+              internalerror(2007091501);
+            diff:=tsetdef(resultdef).setbase div 8;
+            { This is endian-neutral in the new set format: in both cases, }
+            { the first byte contains the first elements of the set.       }
+            { Since the compiler/base rtl cannot contain packed sets before }
+            { they work for big endian, it's no problem that the code below }
+            { is wrong for the old big endian set format (setbase cannot be }
+            { <>0 with non-packed sets).                                    }
+            for i:=0 to tsetdef(resultdef).size-1 do
+              begin
+                Psetbytes(value_set)^[i]:=Psetbytes(value_set)^[i+diff];
+                Psetbytes(value_set)^[i+diff]:=0;
+              end;
+          end;
+      end;
+
+    
+
     function tsetconstnode.dogetcopy : tnode;
 
       var

+ 1 - 0
compiler/options.pas

@@ -2129,6 +2129,7 @@ begin
   def_system_macro('FPC_HAS_LWSYNC');
 {$endif}
   def_system_macro('FPC_HAS_MEMBAR');
+  def_system_macro('FPC_SETBASE_USED');
 
 {$if defined(x86) or defined(arm)}
   def_system_macro('INTERNAL_BACKTRACE');

+ 4 - 1
compiler/ppcgen/ngppcadd.pas

@@ -376,6 +376,7 @@ implementation
     procedure tgenppcaddnode.second_addsmallset;
       var
         cgop   : TOpCg;
+        setbase: aint;
         tmpreg : tregister;
         opdone,
         cmpop  : boolean;
@@ -403,6 +404,7 @@ implementation
         if not(cmpop) then
           location.register := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
 
+        setbase:=tsetdef(left.resultdef).setbase;
         case nodetype of
           addn :
             begin
@@ -416,12 +418,13 @@ implementation
                    internalerror(43244);
                   if (right.location.loc = LOC_CONSTANT) then
                     cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,
-                      aint((aword(1) shl (resultdef.size*8-1)) shr aword(right.location.value)),
+                      aint((aword(1) shl (resultdef.size*8-1)) shr aword(right.location.value-setbase)),
                       left.location.register,location.register)
                   else
                     begin
                       tmpreg := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                       cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,aint((aword(1) shl (resultdef.size*8-1))),tmpreg);
+                      register_maybe_adjust_setbase(current_asmdata.CurrAsmList,right.location,setbase);
                       cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,
                         right.location.register,tmpreg);
                       if left.location.loc <> LOC_CONSTANT then

+ 1 - 0
compiler/ptconst.pas

@@ -574,6 +574,7 @@ implementation
                 Message(parser_e_illegal_expression)
               else
                 begin
+                  tsetconstnode(p).adjustforsetbase;
                   { this writing is endian independant   }
                   { untrue - because they are considered }
                   { arrays of 32-bit values CEC          }

+ 5 - 4
compiler/ptype.pas

@@ -442,9 +442,10 @@ implementation
              case tt2.typ of
                { don't forget that min can be negativ  PM }
                enumdef :
-                 if tenumdef(tt2).min>=0 then
+                 if (tenumdef(tt2).min>=0) and
+                    (tenumdef(tt2).max<=255) then
                   // !! def:=tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
-                  def:=tsetdef.create(tt2,tenumdef(tt2).max)
+                  def:=tsetdef.create(tt2,tenumdef(tt2).min,tenumdef(tt2).max)
                  else
                   Message(sym_e_ill_type_decl_set);
                orddef :
@@ -453,10 +454,10 @@ implementation
                       (torddef(tt2).ordtype<>uwidechar) and
                       (torddef(tt2).low>=0) then
                      // !! def:=tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
-                     if Torddef(tt2).high>int64(high(longint)) then
+                     if Torddef(tt2).high>int64(high(byte)) then
                        message(sym_e_ill_type_decl_set)
                      else
-                       def:=tsetdef.create(tt2,torddef(tt2).high.svalue)
+                       def:=tsetdef.create(tt2,torddef(tt2).low.svalue,torddef(tt2).high.svalue)
                    else
                      Message(sym_e_ill_type_decl_set);
                  end;

+ 33 - 21
compiler/symdef.pas

@@ -547,7 +547,7 @@ interface
           settype  : tsettype;
           setbase,
           setmax   : aword;
-          constructor create(def:tdef;high : aint);
+          constructor create(def:tdef;low, high : aint);
           constructor ppuload(ppufile:tcompilerppufile);
           function getcopy : tstoreddef;override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -2002,33 +2002,45 @@ implementation
                                    TSETDEF
 ***************************************************************************}
 
-    constructor tsetdef.create(def:tdef;high : aint);
+    constructor tsetdef.create(def:tdef;low, high : aint);
+      var
+        setallocbits: aint;
+        packedsavesize: aint;
       begin
          inherited create(setdef);
          elementdef:=def;
-         setbase:=0;
          setmax:=high;
-         if high<32 then
+         if (current_settings.setalloc=0) then
            begin
-             settype:=smallset;
-             if current_settings.setalloc=0 then      { $PACKSET Fixed?}
-               savesize:=Sizeof(longint)
+             setbase:=0;
+             if (high<32) then
+               begin
+                 settype:=smallset;
+                 savesize:=Sizeof(longint)
+               end
+             else if (high<256) then
+               begin
+                 settype:=normset;
+                 savesize:=32
+               end
              else
-               savesize:=current_settings.setalloc*(((high+1)+current_settings.setalloc*8-1) DIV (current_settings.setalloc*8));
-             if savesize=3 then
-               savesize:=4;
+               savesize:=(high+7) div 8
            end
          else
-          if high<256 then
-            begin
-              settype:=normset;
-              if current_settings.setalloc=0 then      { $PACKSET Fixed?}
-                savesize:=32
-              else                       {No, use $PACKSET VALUE for rounding}
-                savesize:=current_settings.setalloc*(((high+1)+current_settings.setalloc*8-1) DIV (current_settings.setalloc*8));
-            end
-          else
-            savesize:=current_settings.setalloc*(((high+1)+current_settings.setalloc*8-1) DIV (current_settings.setalloc*8));
+           begin
+             setallocbits:=current_settings.setalloc*8;
+             setbase:=low and not(setallocbits-1);
+             packedsavesize:=current_settings.setalloc*((((high+setallocbits)-setbase)) DIV setallocbits);
+             savesize:=packedsavesize;
+             if (packedsavesize<=4) then
+               begin
+                 settype:=smallset;
+                 if savesize=3 then
+                   savesize:=4;
+               end
+             else if (packedsavesize<=32) then
+               settype:=normset;
+           end;
       end;
 
 
@@ -2045,7 +2057,7 @@ implementation
 
     function tsetdef.getcopy : tstoreddef;
       begin
-        result:=tsetdef.create(elementdef,setmax);
+        result:=tsetdef.create(elementdef,setbase,setmax);
         { the copy might have been created with a different setalloc setting }
         tsetdef(result).settype:=settype;
         tsetdef(result).savesize:=savesize;

+ 3 - 0
compiler/x86/nx86add.pas

@@ -336,6 +336,7 @@ unit nx86add;
 
     procedure tx86addnode.second_addsmallset;
       var
+        setbase : aint;
         opsize : TCGSize;
         op     : TAsmOp;
         extra_not,
@@ -349,6 +350,7 @@ unit nx86add;
         extra_not:=false;
         all_member_optimization:=false;
         opsize:=int_cgsize(resultdef.size);
+        setbase:=tsetdef(left.resultdef).setbase;
         case nodetype of
           addn :
             begin
@@ -367,6 +369,7 @@ unit nx86add;
                  { bts requires both elements to be registers }
                  location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false);
                  location_force_reg(current_asmdata.CurrAsmList,right.location,opsize,true);
+                 register_maybe_adjust_setbase(current_asmdata.CurrAsmList,right.location,setbase);
                  op:=A_BTS;
                  noswap:=true;
                end

+ 6 - 3
compiler/x86/nx86inl.pas

@@ -464,9 +464,10 @@ implementation
       procedure tx86inlinenode.second_IncludeExclude;
         var
          hregister : tregister;
-         asmop : tasmop;
+         setbase   : aint;
          bitsperop,l : longint;
          cgop : topcg;
+         asmop : tasmop;
          opsize : tcgsize;
         begin
           if not(is_varset(tcallparanode(left).resultdef)) then
@@ -476,10 +477,11 @@ implementation
           bitsperop:=(8*tcgsize2size[opsize]);
           secondpass(tcallparanode(left).left);
           secondpass(tcallparanode(tcallparanode(left).right).left);
+          setbase:=tsetdef(tcallparanode(left).left.resultdef).setbase;
           if tcallparanode(tcallparanode(left).right).left.location.loc=LOC_CONSTANT then
             begin
               { calculate bit position }
-              l:=1 shl (tcallparanode(tcallparanode(left).right).left.location.value mod bitsperop);
+              l:=1 shl ((tcallparanode(tcallparanode(left).right).left.location.value-setbase) mod bitsperop);
 
               { determine operator }
               if inlinenumber=in_include_x_y then
@@ -493,7 +495,7 @@ implementation
                 LOC_REFERENCE :
                   begin
                     inc(tcallparanode(left).left.location.reference.offset,
-                      (tcallparanode(tcallparanode(left).right).left.location.value div bitsperop)*tcgsize2size[opsize]);
+                      ((tcallparanode(tcallparanode(left).right).left.location.value-setbase) div bitsperop)*tcgsize2size[opsize]);
                     cg.a_op_const_ref(current_asmdata.CurrAsmList,cgop,opsize,l,tcallparanode(left).left.location.reference);
                   end;
                 LOC_CREGISTER :
@@ -513,6 +515,7 @@ implementation
                  asmop:=A_BTR;
 
               location_force_reg(current_asmdata.CurrAsmList,tcallparanode(tcallparanode(left).right).left.location,opsize,true);
+              register_maybe_adjust_setbase(current_asmdata.CurrAsmList,tcallparanode(tcallparanode(left).right).left.location,setbase);
               hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
               if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
                 emit_reg_ref(asmop,tcgsize2opsize[opsize],hregister,tcallparanode(left).left.location.reference)

+ 22 - 11
compiler/x86/nx86set.pas

@@ -81,17 +81,18 @@ implementation
            start,stop : byte;    {Start/stop when range; Stop=element when an element.}
          end;
        var
-         genjumps,
-         use_small,
-         ranges     : boolean;
          hreg,hreg2,
          pleftreg   : tregister;
          opsize     : tcgsize;
          orgopsize  : tcgsize;
          setparts   : array[1..8] of Tsetpart;
-         i,numparts : byte;
+         setbase    : aint;
          adjustment : longint;
          l,l2       : tasmlabel;
+         i,numparts : byte;
+         genjumps,
+         use_small,
+         ranges     : boolean;
 {$ifdef CORRECT_SET_IN_FPC}
          AM         : tasmop;
 {$endif CORRECT_SET_IN_FPC}
@@ -282,6 +283,7 @@ implementation
          else
           begin
             location_reset(location,LOC_FLAGS,OS_NO);
+            setbase:=tsetdef(right.resultdef).setbase;
 
             { We will now generated code to check the set itself, no jmps,
               handle smallsets separate, because it allows faster checks }
@@ -295,12 +297,12 @@ implementation
                     LOC_CREGISTER:
                       begin
                          emit_const_reg(A_TEST,TCGSize2OpSize[right.location.size],
-                           1 shl (left.location.value and 31),right.location.register);
+                           1 shl ((left.location.value-setbase) and 31),right.location.register);
                       end;
                     LOC_REFERENCE,
                     LOC_CREFERENCE :
                       begin
-                        emit_const_ref(A_TEST,TCGSize2OpSize[right.location.size],1 shl (left.location.value and 31),
+                        emit_const_ref(A_TEST,TCGSize2OpSize[right.location.size],1 shl ((left.location.value-setbase) and 31),
                            right.location.reference);
                       end;
                     else
@@ -310,6 +312,7 @@ implementation
                else
                 begin
                   location_force_reg(current_asmdata.CurrAsmList,left.location,OS_32,true);
+                  register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
                   if (tcgsize2size[right.location.size] < 4) or
                      (right.location.loc = LOC_CONSTANT) then
                     location_force_reg(current_asmdata.CurrAsmList,right.location,OS_32,true);
@@ -341,8 +344,12 @@ implementation
                   current_asmdata.getjumplabel(l2);
 
                   { load constants to a register }
-                  if left.location.loc=LOC_CONSTANT then
-                    location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
+                  if (left.location.loc=LOC_CONSTANT) or
+                     (setbase<>0) then
+                    begin
+                      location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
+                      register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
+                    end;
 
                   case left.location.loc of
                      LOC_REGISTER,
@@ -384,7 +391,7 @@ implementation
                  but also used if the left side contains values > 32 or < 0 }
                else if left.location.loc=LOC_CONSTANT then
                 begin
-                  if (left.location.value<0) or ((left.location.value shr 3) >= right.resultdef.size) then
+                  if (left.location.value<setbase) or (((left.location.value-setbase) shr 3) >= right.resultdef.size) then
                     {should be caught earlier }
                     internalerror(2007020201);
 
@@ -392,12 +399,12 @@ implementation
                   case right.location.loc of
                     LOC_REFERENCE,LOC_CREFERENCE:
                       begin
-                        inc(right.location.reference.offset,left.location.value shr 3);
+                        inc(right.location.reference.offset,(left.location.value-setbase) shr 3);
                         emit_const_ref(A_TEST,S_B,1 shl (left.location.value and 7),right.location.reference);
                       end;
                     LOC_REGISTER,LOC_CREGISTER:
                       begin
-                        emit_const_reg(A_TEST,TCGSize2OpSize[right.location.size],1 shl (left.location.value),right.location.register);
+                        emit_const_reg(A_TEST,TCGSize2OpSize[right.location.size],1 shl (left.location.value-setbase),right.location.register);
                       end;
                     else
                       internalerror(2007051901);
@@ -426,6 +433,8 @@ implementation
 
                     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 :
                         emit_reg_reg(A_BT,S_L,pleftreg,right.location.register);
@@ -442,6 +451,8 @@ 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);

+ 4 - 0
rtl/inc/compproc.inc

@@ -434,7 +434,11 @@ function fpc_set_comp_sets(const set1,set2: fpc_normal_set): boolean; compilerpr
 function fpc_set_contains_sets(const set1,set2: fpc_normal_set): boolean; compilerproc;
 {$endif ndef FPC_NEW_BIGENDIAN_SETS}
 
+{$ifdef FPC_SETBASE_USED}
+procedure fpc_varset_load(const l;sourcesize : longint;var dest;size,srcminusdstbase : ptrint); compilerproc;
+{$else}
 procedure fpc_varset_load(const l;sourcesize : longint;var dest;size : ptrint); compilerproc;
+{$endif}
 procedure fpc_varset_create_element(b,size : ptrint; var data); compilerproc;
 procedure fpc_varset_set(const source;var dest; b,size : ptrint); compilerproc;
 procedure fpc_varset_unset(const source;var dest; b,size : ptrint); compilerproc;

+ 37 - 0
rtl/inc/genset.inc

@@ -232,6 +232,41 @@ function fpc_set_unset_byte(const source: fpc_normal_set; b : byte): fpc_normal_
 {
   convert sets
 }
+{$ifdef FPC_SETBASE_USED}
+procedure fpc_varset_load(const l;sourcesize : longint;var dest;size,srcminusdstbase : ptrint); compilerproc;
+  var
+    srcptr, dstptr: pointer;
+  begin
+    srcptr:=@l;
+    dstptr:=@dest;
+    { going from a higher base to a lower base, e.g.
+      src: 001f0000, base=2,size=4 -> 0000001f0000 in base 0
+      dstr in base = 1 (-> srcminusdstbase = 1) -> to
+      00001f0000, base=1 -> need to prepend "srcminusdstbase" zero bytes
+    }
+    if (srcminusdstbase>0) then
+      begin
+        { fill the skipped part with 0 }
+        fillchar(dstptr^,srcminusdstbase,0);
+        inc(dstptr,srcminusdstbase);
+        dec(size,srcminusdstbase);
+      end
+    else if (srcminusdstbase<0) then
+      begin
+        { inc/dec switched since srcminusdstbase < 0 }
+        dec(srcptr,srcminusdstbase);
+        inc(sourcesize,srcminusdstbase);
+      end;
+
+    if sourcesize>size then
+      sourcesize:=size;
+    move(srcptr^,dstptr^,sourcesize);
+    { fill the  leftover (if any) with 0 }
+    FillChar((dstptr+sourcesize)^,size-sourcesize,0);
+  end;
+
+{$else FPC_SETBASE_USED}
+
 procedure fpc_varset_load(const l;sourcesize : longint;var dest;size : ptrint); compilerproc;
   begin
     if sourcesize>size then
@@ -239,6 +274,8 @@ procedure fpc_varset_load(const l;sourcesize : longint;var dest;size : ptrint);
     move(l,plongint(@dest)^,sourcesize);
     FillChar((@dest+sourcesize)^,size-sourcesize,0);
   end;
+{$endif FPC_SETBASE_USED}
+
 {$endif ndef FPC_SYSTEM_HAS_FPC_SET_LOAD_SMALL}
 
 

+ 742 - 0
tests/test/cg/taddset3.pp

@@ -0,0 +1,742 @@
+{$ifdef fpc}
+{$packset 1}
+{$endif}
+
+{****************************************************************}
+{  CODE GENERATOR TEST PROGRAM                                   }
+{****************************************************************}
+{ NODE TESTED : secondadd()                                      }
+{****************************************************************}
+{ PRE-REQUISITES: secondload()                                   }
+{                 secondassign()                                 }
+{                 secondsetelement()                             }
+{****************************************************************}
+{ DEFINES:                                                       }
+{            FPC     = Target is FreePascal compiler             }
+{****************************************************************}
+{ REMARKS:                                                       }
+{                                                                }
+{                                                                }
+{                                                                }
+{****************************************************************}
+
+Program tneg;
+
+var
+  Err : boolean;
+
+type
+       { DO NOT CHANGE THE VALUES OF THESE ENUMERATIONS! }
+       tsmallenum = (dA=23,dB,dC,dd,de,df,dg,dh,di,dj,dk,dl,dm,dn,dop,dp,dq,dr);
+       tsmallsubenum = dk..dr;
+       tasmop = (A_ABCD=13,
+         A_ADD,A_ADDA,A_ADDI,A_ADDQ,A_ADDX,A_AND,A_ANDI,
+         A_ASL,A_ASR,A_BCC,A_BCS,A_BEQ,A_BGE,A_BGT,A_BHI,
+         A_BLE,A_BLS,A_BLT,A_BMI,A_BNE,A_BPL,A_BVC,A_BVS,
+         A_BCHG,A_BCLR,A_BRA,A_BSET,A_BSR,A_BTST,A_CHK,
+         A_CLR,A_CMP,A_CMPA,A_CMPI,A_CMPM,A_DBCC,A_DBCS,A_DBEQ,A_DBGE,
+         A_DBGT,A_DBHI,A_DBLE,A_DBLS,A_DBLT,A_DBMI,A_DBNE,A_DBRA,
+         A_DBPL,A_DBT,A_DBVC,A_DBVS,A_DBF,A_DIVS,A_DIVU,
+         A_EOR,A_EORI,A_EXG,A_ILLEGAL,A_EXT,A_JMP,A_JSR,
+         A_LEA,A_LINK,A_LSL,A_LSR,A_MOVE,A_MOVEA,A_MOVEI,A_MOVEQ,
+         A_MOVEM,A_MOVEP,A_MULS,A_MULU,A_NBCD,A_NEG,A_NEGX,
+         A_NOP,A_NOT,A_OR,A_ORI,A_PEA,A_ROL,A_ROR,A_ROXL,
+         A_ROXR,A_RTR,A_RTS,A_SBCD,A_SCC,A_SCS,A_SEQ,A_SGE,
+         A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,A_SNE,
+         A_SPL,A_ST,A_SVC,A_SVS,A_SF,A_SUB,A_SUBA,A_SUBI,A_SUBQ,
+         A_SUBX,A_SWAP,A_TAS,A_TRAP,A_TRAPV,A_TST,A_UNLK,
+         A_RTE,A_RESET,A_STOP,
+         { MC68010 instructions }
+         A_BKPT,A_MOVEC,A_MOVES,A_RTD,
+         { MC68020 instructions }
+         A_BFCHG,A_BFCLR,A_BFEXTS,A_BFEXTU,A_BFFFO,
+         A_BFINS,A_BFSET,A_BFTST,A_CALLM,A_CAS,A_CAS2,
+         A_CHK2,A_CMP2,A_DIVSL,A_DIVUL,A_EXTB,A_PACK,A_RTM,
+         A_TRAPCC,A_TRACS,A_TRAPEQ,A_TRAPF,A_TRAPGE,A_TRAPGT,
+         A_TRAPHI,A_TRAPLE,A_TRAPLS,A_TRAPLT,A_TRAPMI,A_TRAPNE,
+         A_TRAPPL,A_TRAPT,A_TRAPVC,A_TRAPVS,A_UNPK,
+         { FPU Processor instructions - directly supported only. }
+         { IEEE aware and misc. condition codes not supported   }
+         A_FABS,A_FADD,
+         A_FBEQ,A_FBNE,A_FBNGT,A_FBGT,A_FBGE,A_FBNGE,
+         A_FBLT,A_FBNLT,A_FBLE,A_FBGL,A_FBNGL,A_FBGLE,A_FBNGLE,
+         A_FDBEQ,A_FDBNE,A_FDBGT,A_FDBNGT,A_FDBGE,A_FDBNGE,
+         A_FDBLT,A_FDBNLT,A_FDBLE,A_FDBGL,A_FDBNGL,A_FDBGLE,A_FBDNGLE,
+         A_FSEQ,A_FSNE,A_FSGT,A_FSNGT,A_FSGE,A_FSNGE,
+         A_FSLT,A_FSNLT,A_FSLE,A_FSGL,A_FSNGL,A_FSGLE,A_FSNGLE,
+         A_FCMP,A_FDIV,A_FMOVE,A_FMOVEM,
+         A_FMUL,A_FNEG,A_FNOP,A_FSQRT,A_FSUB,A_FSGLDIV,
+         A_FSFLMUL,A_FTST,
+         A_FTRAPEQ,A_FTRAPNE,A_FTRAPGT,A_FTRAPNGT,A_FTRAPGE,A_FTRAPNGE,
+         A_FTRAPLT,A_FTRAPNLT,A_FTRAPLE,A_FTRAPGL,A_FTRAPNGL,A_FTRAPGLE,A_FTRAPNGLE,
+         { Protected instructions }
+         A_CPRESTORE,A_CPSAVE,
+         { FPU Unit protected instructions                    }
+         { and 68030/68851 common MMU instructions            }
+         { (this may include 68040 MMU instructions)          }
+         A_FRESTORE,A_FSAVE,A_PFLUSH,A_PFLUSHA,A_PLOAD,A_PMOVE,A_PTEST,
+         { Useful for assembly langage output }
+         A_LABEL,A_NONE);
+       tsubasmop = A_BFINS..A_FSEQ;
+       tsubasmop2 = A_BCS..A_BHI;
+
+
+
+type
+  topset = set of tasmop;
+  tsubopset = set of tsubasmop;
+  tsmallset = set of tsmallenum;
+  tsubsmallset = set of tsmallsubenum;
+
+const
+
+   { NORMAL SETS }
+   constset1 : array[1..3] of topset =
+   (
+       { 66 }    { 210 }  { 225 }
+     ([A_MOVE,    { 66  : LONG 2 - BIT 2  }
+       A_FTST,    { 210 : LONG 6 - BIT 18 }
+       A_CPSAVE]),{ 225 : LONG 7 - BIT 1 }
+       { 1..8 }
+     ([A_ADD..A_ASL]),
+       { 134 }
+     ([A_CHK2])
+   );
+
+   constset2 : array[1..4] of topset =
+   (
+     ([A_MOVE,A_FTST,A_CPSAVE]),
+     ([A_ADD..A_ASL]),
+     ([A_CHK2]),
+     ([A_CMP2,A_TRAPVC,A_FADD])
+   );
+
+   { SMALL SETS }
+   constset3 : array[1..3] of tsmallset =
+   (
+     ([DA,             { 0 :  LONG 0 : bit 0 }
+       DD,             { 3 :  LONG 0 : bit 3 }
+       DM]),           { 12 :  LONG 0 : bit 12  }
+     ([DB..DI]),       { 1..8 : LONG 0 : bits 1-8  }
+     ([DR])            { 17 :  LONG 0 : bit 17 }
+   );
+
+   constset4 : array[1..3] of tsmallset =
+   (
+     ([DA,DD,DM]),
+     ([DB..DI]),
+     ([DR])
+   );
+
+   constsubset1: array[1..1] of tsubopset =
+   (
+     ([A_CMP2,A_TRAPVC,A_FADD])
+   );
+
+
+ procedure CheckPassed(passed:boolean);
+ begin
+   if passed then
+     WriteLn('Success.')
+   else
+     begin
+       WriteLn('Failure.');
+       Halt(1);
+       Err:=true;
+     end;
+ end;
+
+ procedure SetTestEqual;
+ { FPC_SET_COMP_SETS }
+  var
+    op2list :set of tasmop;
+    oplist: set of tasmop;
+    soplist : tsubopset;
+    soplist2: set of tsubasmop2;
+    passed : boolean;
+  Begin
+   Write('Normal Set == Normal Set test...');
+   passed := true;
+   op2list:=[];
+   oplist:=[];
+   soplist:=[];
+   soplist2:=[];
+   if not (oplist=op2list) then
+     passed := false;
+   if not (soplist=op2list) then
+     passed := false;
+   if not(soplist=soplist2) then
+     passed:=false;
+   if not (constset1[2] = constset2[2]) then
+     passed := false;
+   if not(constset2[4] = constsubset1[1]) then
+     passed:=false;
+   if (constset1[1] = constset2[2]) then
+     passed := false;
+   if (constset1[1] = constsubset1[1]) then
+     passed := false;
+   if soplist2 = constsubset1[1] then
+     passed:=false;
+   if not (constset1[1] = [A_MOVE,A_FTST,A_CPSAVE]) then
+     passed := false;
+   if not (constsubset1[1] = [A_CMP2,A_TRAPVC,A_FADD]) then
+     passed := false;
+    CheckPassed(passed);
+  end;
+
+ procedure SetTestNotEqual;
+ { FPC_SET_COMP_SETS }
+  var
+    op2list :set of tasmop;
+    oplist: set of tasmop;
+    soplist: set of tsubasmop;
+    passed : boolean;
+  Begin
+   Write('Normal Set <> Normal Set test...');
+   passed := true;
+   op2list:=[];
+   oplist:=[];
+   soplist:=[];
+   if not (oplist=op2list) then
+     passed := false;
+   if not (oplist=soplist) then
+     passed := false;
+   if (constset1[2] <> constset2[2]) then
+     passed := false;
+   if not (constset1[1] <> constset2[2]) then
+     passed := false;
+{   if ( [A_ADD] <> [A_ADD] ) then optimized out.
+     passed := false;
+   if ( [A_BLE..A_BPL] <> [A_BLE..A_BPL] ) then
+     passed := false; }
+   if (constset1[1] <> [A_MOVE,A_FTST,A_CPSAVE]) then
+     passed := false;
+    CheckPassed(passed);
+  end;
+
+  procedure SetTestLt;
+  var
+    op2list :set of tasmop;
+    oplist: set of tasmop;
+    soplist : tsubopset;
+    soplist2: set of tsubasmop2;
+    passed : boolean;
+   begin
+    Write('Normal Set <= Normal Set test...');
+    passed := true;
+    if constset1[1] <= constset2[2] then
+      passed := false;
+    if constset1[1] <= constsubset1[1] then
+      passed := false;
+    oplist := [];
+    op2list := [A_MOVE];
+    if op2list <= oplist then
+     passed := false;
+    oplist := [A_MOVE,A_CPRESTORE..A_CPSAVE];
+    if oplist <= op2list then
+     passed := false;
+    soplist2:=[A_BHI];
+    soplist:=[A_BFINS..A_FSEQ];
+    if soplist2<=soplist then
+     passed:=false;
+    CheckPassed(passed);
+   end;
+
+  Procedure SetTestAddOne;
+ { FPC_SET_SET_BYTE }
+ { FPC_SET_ADD_SETS }
+    var
+     op : tasmop;
+     sop : tsubasmop;
+     sop2: tsubasmop2;
+     oplist: set of tasmop;
+     soplist: set of tsubasmop;
+     soplist2, soplist3: set of tsubasmop2;
+     passed: boolean;
+  Begin
+    Write('Set + Set element testing...');
+    passed:=true;
+    op:=A_LABEL;
+    oplist:=[];
+    oplist:=oplist+[op];
+    if oplist<>[A_LABEL] then
+      passed:=false;
+
+    sop:=A_UNPK;
+    oplist:=[];
+    oplist:=[sop];
+    if oplist<>[A_UNPK] then
+      passed:=false;
+
+    soplist:=[];
+    op:=A_UNPK;
+    soplist:=[op];
+    if soplist<>[A_UNPK] then
+      passed:=false;
+
+    soplist:=[];
+    op:=A_FBLE;
+    sop:=A_FABS;
+    soplist:=[op,sop];
+    if soplist<>[A_FBLE,A_FABS] then
+      passed:=false;
+
+    soplist:=[];
+    soplist:=[sop,op];
+    if soplist<>[A_FBLE,A_FABS] then
+      passed:=false;
+
+    oplist:=[];
+    oplist:=soplist+[A_FADD];
+    if (oplist<>[A_FBLE,A_FABS,A_FADD]) then
+      passed:=false;
+
+    oplist:=[];
+    sop:=A_UNPK;
+    oplist:=soplist+[sop];
+    if (oplist<>[A_FBLE,A_FABS,A_UNPK]) then
+      passed:=false;
+
+    soplist2:=[];
+    oplist:=soplist2+[A_BGE];
+    if (oplist<>[A_BGE]) then
+     passed:=false;
+    include(soplist2,A_BGT);
+    oplist:=soplist2-[A_BHI];
+    if (oplist<>[A_BGT]) then
+     passed:=false;
+    soplist3:=[A_BGT,A_BHI];
+    oplist:=soplist2*soplist3;
+    if (oplist<>[A_BGT]) then
+     passed:=false;
+    sop2:=A_BHI;
+    oplist:=[sop2];
+    if (oplist<>[A_BHI]) then
+     passed:=false;
+    CheckPassed(passed);
+  end;
+
+Procedure SetTestAddTwo;
+{ SET_ADD_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('Complex Set + Set element testing...');
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_LABEL];
+ oplist:=op2list+oplist;
+ CheckPassed(oplist = [A_MOVE,A_JSR,A_LABEL]);
+end;
+
+
+
+
+
+Procedure SetTestSubOne;
+{ SET_SUB_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+ op :tasmop;
+ passed : boolean;
+Begin
+ Write('Set - Set element testing...');
+ passed := true;
+ op2list:=[];
+ oplist:=[];
+ op := A_TRACS;
+ oplist:=[A_MOVE]+[A_JSR]+[op];
+ op2list:=[A_MOVE]+[A_JSR];
+ oplist:=oplist-op2list;
+ if oplist <> [A_TRACS] then
+   passed := false;
+
+ oplist:=[A_MOVE]+[A_JSR]+[op];
+ op2list:=[A_MOVE]+[A_JSR];
+ oplist:=op2list-oplist;
+ if oplist <> [] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+Procedure SetTestSubTwo;
+{ FPC_SET_SUB_SETS }
+const
+ b: tasmop = (A_BSR);
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+ op : tasmop;
+ passed : boolean;
+Begin
+ Write('Complex Set - Set element testing...');
+ op := A_BKPT;
+ passed := true;
+ oplist:=[A_MOVE]+[A_JSR]-[op];
+ op2list:=[A_MOVE]+[A_JSR];
+ if oplist <> op2list then
+   passed := false;
+ oplist := [A_MOVE];
+ oplist := oplist - [A_MOVE];
+ if oplist <> [] then
+   passed := false;
+ oplist := oplist + [b];
+ if oplist <> [b] then
+   passed := false;
+ oplist := oplist - [b];
+ if oplist <> [] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+
+Procedure SetTestMulSets;
+{ FPC_SET_MUL_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+ passed : boolean;
+Begin
+ passed := true;
+ Write('Set * Set element testing...');
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE];
+ oplist:=oplist*op2list;
+ if oplist <> [A_JSR] then
+   passed := false;
+ oplist := [A_MOVE,A_FTST];
+ op2list := [A_MOVE,A_FTST];
+ oplist := oplist * op2list;
+ if oplist <> [A_MOVE,A_FTST] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+procedure SetTestRange;
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+ passed : boolean;
+ op1 : tasmop;
+ op2 : tasmop;
+begin
+ passed := true;
+ Write('Range Set + element testing...');
+ op1 := A_ADD;
+ op2 := A_ASL;
+ oplist := [];
+ oplist := [op1..op2];
+ if oplist <> constset1[2] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+procedure SetTestByte;
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+ passed : boolean;
+ op1 : tasmop;
+ op2 : tasmop;
+ op : tasmop;
+begin
+ Write('Simple Set + element testing...');
+ passed := true;
+ op := A_LABEL;
+ oplist := [A_MOVE,op,A_JSR];
+ if oplist <> [A_MOVE,A_LABEL,A_JSR] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+
+{------------------------------ TESTS FOR SMALL VALUES ---------------------}
+ procedure SmallSetTestEqual;
+  var
+    op2list :set of tsmallenum;
+    oplist: set of tsmallenum;
+    passed : boolean;
+  Begin
+   Write('Small Set == Small Set test...');
+   passed := true;
+   op2list:=[];
+   oplist:=[];
+   if not (oplist=op2list) then
+     passed := false;
+   if not (constset3[2] = constset4[2]) then
+     passed := false;
+   if (constset3[1] = constset4[2]) then
+     passed := false;
+   if not (constset3[1] = [DA,DD,DM]) then
+     passed := false;
+ CheckPassed(passed);
+  end;
+
+ procedure SmallSetTestNotEqual;
+  var
+    op2list :set of tsmallenum;
+    oplist: set of tsmallenum;
+    passed : boolean;
+  Begin
+   Write('Small Set <> Small Set test...');
+   passed := true;
+   op2list:=[];
+   oplist:=[];
+   if not (oplist=op2list) then
+     passed := false;
+   if (constset3[2] <> constset4[2]) then
+     passed := false;
+   if not (constset3[1] <> constset4[2]) then
+     passed := false;
+{   if ( [A_ADD] <> [A_ADD] ) then optimized out.
+     passed := false;
+   if ( [A_BLE..A_BPL] <> [A_BLE..A_BPL] ) then
+     passed := false; }
+   if (constset3[1] <> [DA,DD,DM]) then
+     passed := false;
+ CheckPassed(passed);
+  end;
+
+  procedure SmallSetTestLt;
+  var
+    op2list :set of tsmallenum;
+    oplist: set of tsmallenum;
+    passed : boolean;
+   begin
+    Write('Small Set <= Small Set test...');
+    passed := true;
+    if constset3[1] <= constset4[2] then
+      passed := false;
+    oplist := [];
+    op2list := [DC];
+    if op2list <= oplist then
+     passed := false;
+    oplist := [DC,DF..DM];
+    if oplist <= op2list then
+     passed := false;
+ CheckPassed(passed);
+   end;
+
+  Procedure SmallSetTestAddOne;
+    var
+     op : tsmallenum;
+     oplist: set of tsmallenum;
+  Begin
+    Write('Small Set + Small Set element testing...');
+    op:=DG;
+    oplist:=[];
+    oplist:=oplist+[op];
+    CheckPassed( oplist = [DG] );
+  end;
+
+Procedure SmallSetTestAddTwo;
+var
+ op2list :set of tsmallenum;
+ oplist: set of tsmallenum;
+Begin
+ Write('Small Complex Set + Small Set element testing...');
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DG]+[DI];
+ op2list:=[DM];
+ oplist:=op2list+oplist;
+ CheckPassed( oplist = [DG,DI,DM] );
+end;
+
+
+Procedure SmallSetTestSubOne;
+var
+ op2list :set of tsmallenum;
+ oplist: set of tsmallenum;
+ op :tsmallenum;
+ passed : boolean;
+Begin
+ Write('Small Set - Small Set element testing...');
+ passed := true;
+ op2list:=[];
+ oplist:=[];
+ op := DL;
+ oplist:=[DG]+[DI]+[op];
+ op2list:=[DG]+[DI];
+ oplist:=oplist-op2list;
+ if oplist <> [DL] then
+   passed := false;
+
+ oplist:=[DG]+[DI]+[op];
+ op2list:=[DG]+[DI];
+ oplist:=op2list-oplist;
+ if oplist <> [] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+Procedure SmallSetTestSubTwo;
+const
+ b: tsmallenum = (DH);
+var
+ op2list :set of tsmallenum;
+ oplist: set of tsmallenum;
+ op : tsmallenum;
+ passed : boolean;
+Begin
+ Write('Small Complex Set - Small Set element testing...');
+ op := DL;
+ passed := true;
+ oplist:=[DG]+[DI]-[op];
+ op2list:=[DG]+[DI];
+ if oplist <> op2list then
+   passed := false;
+ oplist := [DG];
+ oplist := oplist - [DG];
+ if oplist <> [] then
+   passed := false;
+ oplist := oplist + [b];
+ if oplist <> [b] then
+   passed := false;
+ oplist := oplist - [b];
+ if oplist <> [] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+
+Procedure SmallSetTestMulSets;
+var
+ op2list : set of tsmallenum;
+ oplist: set of tsmallenum;
+ passed : boolean;
+Begin
+ passed := true;
+ Write('Small Set * Small Set element testing...');
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DG]+[DI];
+ op2list:=[DG];
+ oplist:=oplist*op2list;
+ if oplist <> [DI] then
+   passed := false;
+ oplist := [DG,DK];
+ op2list := [DG,DK];
+ oplist := oplist * op2list;
+ if oplist <> [DG,DK] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+procedure SmallSetTestRange;
+var
+ op2list :set of tsmallenum;
+ oplist: set of tsmallenum;
+ passed : boolean;
+ op1 : tsmallenum;
+ op2 : tsmallenum;
+begin
+ passed := true;
+ Write('Small Range Set + element testing...');
+ op1 := DB;
+ op2 := DI;
+ oplist := [];
+ oplist := [op1..op2];
+ if oplist <> constset3[2] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+procedure SmallSetTestByte;
+var
+ op2list : set of tsmallenum;
+ oplist: set of tsmallenum;
+ passed : boolean;
+ op1 : tsmallenum;
+ op2 : tsmallenum;
+ op : tsmallenum;
+begin
+ Write('Small Simple Set + element testing...');
+ passed := true;
+ op := DD;
+ oplist := [DG,op,DI];
+ if oplist <> [DG,DD,DI] then
+   passed := false;
+ CheckPassed(passed);
+end;
+
+(*
+
+const
+ b: myenum = (dA);
+var
+ enum: set of myenum;
+ oplist: set of tasmop;
+ l : word;
+Begin
+  SetTestEqual;
+  SetTestNotEqual;
+{ small sets }
+ enum:=[];
+ { add }
+ enum:=enum+[da];
+ { subtract }
+ enum:=enum-[da];
+ if DA in enum then
+  WriteLn('Found A_LABEL');
+ { very large sets       }
+ { copy loop test        }
+ WRITELN('LARGE SETS:');
+ oplist := [A_LABEL];
+ { secondin test         }
+ if A_LABEL in oplist then
+  WriteLn('TESTING SIMPLE SECOND_IN: PASSED.');
+ { }
+ oplist:=[];
+ if A_LABEL in oplist then
+  WriteLn('SECOND IN FAILED.');
+{ SecondinSets;}
+ SetSetByte;
+ SetAddSets;
+ SetSubSets;
+ SetCompSets;
+ SetMulSets;
+ WRITELN('SMALL SETS:');
+ SmallInSets;
+ SmallAddSets;
+ SmallSubSets;
+ SmallCompSets;
+ SmallMulSets;
+ l:=word(A_CPRESTORE);
+ if l = word(A_CPRESTORE) then
+  Begin
+  end;
+
+*)
+Begin
+  WriteLn('----------------------- Normal sets -----------------------');
+  { Normal sets }
+  SetTestEqual;
+  SetTestNotEqual;
+  SetTestAddOne;
+  SetTestAddTwo;
+  SetTestSubOne;
+  SetTestSubTwo;
+  SetTestRange;
+  SetTestLt;
+  SetTestByte;
+  { Small sets }
+  WriteLn('----------------------- Small sets -----------------------');
+  SmallSetTestEqual;
+  SmallSetTestNotEqual;
+  SmallSetTestAddOne;
+  SmallSetTestAddTwo;
+  SmallSetTestSubOne;
+  SmallSetTestSubTwo;
+  SmallSetTestRange;
+  SmallSetTestLt;
+  SmallSetTestByte;
+
+  if Err then
+   Halt(1);
+end.

+ 492 - 0
tests/test/tset2a.pp

@@ -0,0 +1,492 @@
+(*********************************************************************)
+(* Copyright (C) 1998, Carl Eric Codere                              *)
+(*********************************************************************)
+(* FPC (Free Pascal compiler) testsuite: SETS                        *)
+(*   Tests the following: in, +, -, *, assignments.                  *)
+(*      for small sets amd large sets, both with constants           *)
+(*      and variables.                                               *)
+(*********************************************************************)
+
+{$packset 1}
+
+const
+  failed: boolean = false;
+
+type
+       myenum = (dA:=8,dB,dC,dd,dedf,dg,dh,di,dj,dk,dl,dm,dn);
+       tasmop = (A_ABCD:=16,
+         A_ADD,A_ADDA,A_ADDI,A_ADDQ,A_ADDX,A_AND,A_ANDI,
+         A_ASL,A_ASR,A_BCC,A_BCS,A_BEQ,A_BGE,A_BGT,A_BHI,
+         A_BLE,A_BLS,A_BLT,A_BMI,A_BNE,A_BPL,A_BVC,A_BVS,
+         A_BCHG,A_BCLR,A_BRA,A_BSET,A_BSR,A_BTST,A_CHK,
+         A_CLR,A_CMP,A_CMPA,A_CMPI,A_CMPM,A_DBCC,A_DBCS,A_DBEQ,A_DBGE,
+         A_DBGT,A_DBHI,A_DBLE,A_DBLS,A_DBLT,A_DBMI,A_DBNE,A_DBRA,
+         A_DBPL,A_DBT,A_DBVC,A_DBVS,A_DBF,A_DIVS,A_DIVU,
+         A_EOR,A_EORI,A_EXG,A_ILLEGAL,A_EXT,A_JMP,A_JSR,
+         A_LEA,A_LINK,A_LSL,A_LSR,A_MOVE,A_MOVEA,A_MOVEI,A_MOVEQ,
+         A_MOVEM,A_MOVEP,A_MULS,A_MULU,A_NBCD,A_NEG,A_NEGX,
+         A_NOP,A_NOT,A_OR,A_ORI,A_PEA,A_ROL,A_ROR,A_ROXL,
+         A_ROXR,A_RTR,A_RTS,A_SBCD,A_SCC,A_SCS,A_SEQ,A_SGE,
+         A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,A_SNE,
+         A_SPL,A_ST,A_SVC,A_SVS,A_SF,A_SUB,A_SUBA,A_SUBI,A_SUBQ,
+         A_SUBX,A_SWAP,A_TAS,A_TRAP,A_TRAPV,A_TST,A_UNLK,
+         A_RTE,A_RESET,A_STOP,
+         { MC68010 instructions }
+         A_BKPT,A_MOVEC,A_MOVES,A_RTD,
+         { MC68020 instructions }
+         A_BFCHG,A_BFCLR,A_BFEXTS,A_BFEXTU,A_BFFFO,
+         A_BFINS,A_BFSET,A_BFTST,A_CALLM,A_CAS,A_CAS2,
+         A_CHK2,A_CMP2,A_DIVSL,A_DIVUL,A_EXTB,A_PACK,A_RTM,
+         A_TRAPCC,A_TRACS,A_TRAPEQ,A_TRAPF,A_TRAPGE,A_TRAPGT,
+         A_TRAPHI,A_TRAPLE,A_TRAPLS,A_TRAPLT,A_TRAPMI,A_TRAPNE,
+         A_TRAPPL,A_TRAPT,A_TRAPVC,A_TRAPVS,A_UNPK,
+         { FPU Processor instructions - directly supported only. }
+         { IEEE aware and misc. condition codes not supported   }
+         A_FABS,A_FADD,
+         A_FBEQ,A_FBNE,A_FBNGT,A_FBGT,A_FBGE,A_FBNGE,
+         A_FBLT,A_FBNLT,A_FBLE,A_FBGL,A_FBNGL,A_FBGLE,A_FBNGLE,
+         A_FDBEQ,A_FDBNE,A_FDBGT,A_FDBNGT,A_FDBGE,A_FDBNGE,
+         A_FDBLT,A_FDBNLT,A_FDBLE,A_FDBGL,A_FDBNGL,A_FDBGLE,A_FBDNGLE,
+         A_FSEQ,A_FSNE,A_FSGT,A_FSNGT,A_FSGE,A_FSNGE,
+         A_FSLT,A_FSNLT,A_FSLE,A_FSGL,A_FSNGL,A_FSGLE,A_FSNGLE,
+         A_FCMP,A_FDIV,A_FMOVE,A_FMOVEM,
+         A_FMUL,A_FNEG,A_FNOP,A_FSQRT,A_FSUB,A_FSGLDIV,
+         A_FSFLMUL,A_FTST,
+         A_FTRAPEQ,A_FTRAPNE,A_FTRAPGT,A_FTRAPNGT,A_FTRAPGE,A_FTRAPNGE,
+         A_FTRAPLT,A_FTRAPNLT,A_FTRAPLE,A_FTRAPGL,A_FTRAPNGL,A_FTRAPGLE,A_FTRAPNGLE,
+         { Protected instructions }
+         A_CPRESTORE,A_CPSAVE,
+         { FPU Unit protected instructions                    }
+         { and 68030/68851 common MMU instructions            }
+         { (this may include 68040 MMU instructions)          }
+         A_FRESTORE,A_FSAVE,A_PFLUSH,A_PFLUSHA,A_PLOAD,A_PMOVE,A_PTEST,
+         { Useful for assembly langage output }
+         A_LABEL,A_NONE);
+
+
+Function X(y:myenum): myenum;
+Begin
+ x:=y;
+end;
+
+
+Procedure SecondInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op,op2 : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_IN_BYTE:');
+ oplist:=[];
+ op:=A_JSR;
+ if A_JSR in oplist then
+  begin
+    WriteLn('A_JSR in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('A_JSR in [] PASSED.');
+ if op in oplist then
+  begin
+    WriteLn('op(A_JSR) in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('op (A_JSR) in [] PASSED.');
+ op:=A_MOVE;
+ oplist:=oplist+[A_MOVE];
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+ if op in oplist then
+  WriteLn('op(A_MOVE) in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('op(A_MOVE) in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+  op:=A_MOVE;
+  oplist:=[];
+  oplist:=[A_SUB]+[op];
+  op2:=A_MOVE;
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+ if op2 in oplist then
+  WriteLn('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSetByte;
+{ SET_SET_BYTE }
+var
+ op : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_SET_BYTE(1):');
+ op:=A_LABEL;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true
+ end;
+ Write('TESTING INCLUDE:');
+ op:=A_RTE;
+ include(oplist,op);
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SetAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_LABEL];
+ oplist:=op2list+oplist;
+ if A_MOVE in oplist then
+  if A_LABEL in oplist then
+   if A_JSR in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+ else
+  begin
+    WriteLn('TESTING SET_ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ oplist:=op2list-oplist;
+ if (A_MOVE in oplist) or (A_LABEL in oplist) or (A_JSR in oplist) then
+   begin
+    WriteLn('TESTING SET_SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_SUB_SETS: PASSED.');
+ oplist := [A_MOVE,A_RTE];
+ exclude(oplist,A_MOVE);
+ if (A_MOVE in oplist) then
+  begin
+    WriteLn('TESTING EXCLUDE: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING EXCLUDE: PASSED.')
+end;
+
+Procedure SetCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ if oplist=op2list then
+  WriteLn('TESTING SET_COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[A_MOVE];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING SET_COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_COMP_SETS(2): PASSED.');
+end;
+
+Procedure SetMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE];
+ oplist:=oplist*op2list;
+ if A_JSR in oplist then
+  begin
+    WriteLn('TESTING SET_MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_MUL_SETS(1): PASSED.');
+ if A_MOVE in oplist  then
+  WriteLn('TESTING SET_MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+{------------------------------ TESTS FOR SMALL VALUES ---------------------}
+Procedure SmallInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING IN_BYTE:');
+ oplist:=[];
+ op:=Dn;
+ if op in oplist then
+  begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+ op:=dm;
+ oplist:=oplist+[Dm];
+ if op in oplist then
+  WriteLn(' PASSED.')
+ else
+   begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSetByte;
+{ SET_SET_BYTE }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING SET_BYTE(1):');
+ op:=DA;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SmallAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DB];
+ oplist:=op2list+oplist;
+ if DA in oplist then
+  if DC in oplist then
+   if DB in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+   begin
+     WriteLn('TESTING ADD_SETS: FAILED.');
+     failed := true
+   end
+ else
+  begin
+    WriteLn('TESTING ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ oplist:=op2list-oplist;
+ if (DA in oplist) or (DB in oplist) or (DC in oplist) then
+  begin
+    WriteLn('TESTING SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SUB_SETS: PASSED.')
+end;
+
+Procedure SmallCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ if oplist=op2list then
+  WriteLn('TESTING COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[DA];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING COMP_SETS(2): PASSED.');
+end;
+
+Procedure SmallMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA];
+ oplist:=oplist*op2list;
+ if DC in oplist then
+  begin
+    WriteLn('TESTING MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING MUL_SETS(1): PASSED.');
+ if DA in oplist  then
+  WriteLn('TESTING MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+const
+ b: myenum = (dA);
+var
+ enum: set of myenum;
+ oplist: set of tasmop;
+ l : word;
+Begin
+{ small sets }
+ enum:=[];
+ { add }
+ enum:=enum+[da];
+ { subtract }
+ enum:=enum-[da];
+ if DA in enum then
+  WriteLn('Found A_LABEL');
+ { very large sets       }
+ { copy loop test        }
+ WRITELN('LARGE SETS:');
+ oplist := [A_LABEL];
+ { secondin test         }
+ if A_LABEL in oplist then
+  WriteLn('TESTING SIMPLE SECOND_IN: PASSED.')
+ else
+   begin
+    failed := true
+  end;
+
+ { }
+ oplist:=[];
+ if A_LABEL in oplist then
+   begin
+    WriteLn('SECOND IN FAILED.');
+    failed := true
+  end;
+ SecondinSets;
+ SetSetByte;
+ SetAddSets;
+ SetSubSets;
+ SetCompSets;
+ SetMulSets;
+ WRITELN('SMALL SETS:');
+ SmallInSets;
+ SmallAddSets;
+ SmallSubSets;
+ SmallCompSets;
+ SmallMulSets;
+ l:=word(A_CPRESTORE);
+ if l = word(A_CPRESTORE) then
+  Begin
+  end
+  else failed := true;
+
+  if failed then
+    begin
+      WriteLn('One or more test failed');
+      Halt(1);
+    end;
+end.

+ 492 - 0
tests/test/tset2b.pp

@@ -0,0 +1,492 @@
+(*********************************************************************)
+(* Copyright (C) 1998, Carl Eric Codere                              *)
+(*********************************************************************)
+(* FPC (Free Pascal compiler) testsuite: SETS                        *)
+(*   Tests the following: in, +, -, *, assignments.                  *)
+(*      for small sets amd large sets, both with constants           *)
+(*      and variables.                                               *)
+(*********************************************************************)
+
+{$packset 2}
+
+const
+  failed: boolean = false;
+
+type
+       myenum = (dA:=8,dB,dC,dd,dedf,dg,dh,di,dj,dk,dl,dm,dn);
+       tasmop = (A_ABCD:=16,
+         A_ADD,A_ADDA,A_ADDI,A_ADDQ,A_ADDX,A_AND,A_ANDI,
+         A_ASL,A_ASR,A_BCC,A_BCS,A_BEQ,A_BGE,A_BGT,A_BHI,
+         A_BLE,A_BLS,A_BLT,A_BMI,A_BNE,A_BPL,A_BVC,A_BVS,
+         A_BCHG,A_BCLR,A_BRA,A_BSET,A_BSR,A_BTST,A_CHK,
+         A_CLR,A_CMP,A_CMPA,A_CMPI,A_CMPM,A_DBCC,A_DBCS,A_DBEQ,A_DBGE,
+         A_DBGT,A_DBHI,A_DBLE,A_DBLS,A_DBLT,A_DBMI,A_DBNE,A_DBRA,
+         A_DBPL,A_DBT,A_DBVC,A_DBVS,A_DBF,A_DIVS,A_DIVU,
+         A_EOR,A_EORI,A_EXG,A_ILLEGAL,A_EXT,A_JMP,A_JSR,
+         A_LEA,A_LINK,A_LSL,A_LSR,A_MOVE,A_MOVEA,A_MOVEI,A_MOVEQ,
+         A_MOVEM,A_MOVEP,A_MULS,A_MULU,A_NBCD,A_NEG,A_NEGX,
+         A_NOP,A_NOT,A_OR,A_ORI,A_PEA,A_ROL,A_ROR,A_ROXL,
+         A_ROXR,A_RTR,A_RTS,A_SBCD,A_SCC,A_SCS,A_SEQ,A_SGE,
+         A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,A_SNE,
+         A_SPL,A_ST,A_SVC,A_SVS,A_SF,A_SUB,A_SUBA,A_SUBI,A_SUBQ,
+         A_SUBX,A_SWAP,A_TAS,A_TRAP,A_TRAPV,A_TST,A_UNLK,
+         A_RTE,A_RESET,A_STOP,
+         { MC68010 instructions }
+         A_BKPT,A_MOVEC,A_MOVES,A_RTD,
+         { MC68020 instructions }
+         A_BFCHG,A_BFCLR,A_BFEXTS,A_BFEXTU,A_BFFFO,
+         A_BFINS,A_BFSET,A_BFTST,A_CALLM,A_CAS,A_CAS2,
+         A_CHK2,A_CMP2,A_DIVSL,A_DIVUL,A_EXTB,A_PACK,A_RTM,
+         A_TRAPCC,A_TRACS,A_TRAPEQ,A_TRAPF,A_TRAPGE,A_TRAPGT,
+         A_TRAPHI,A_TRAPLE,A_TRAPLS,A_TRAPLT,A_TRAPMI,A_TRAPNE,
+         A_TRAPPL,A_TRAPT,A_TRAPVC,A_TRAPVS,A_UNPK,
+         { FPU Processor instructions - directly supported only. }
+         { IEEE aware and misc. condition codes not supported   }
+         A_FABS,A_FADD,
+         A_FBEQ,A_FBNE,A_FBNGT,A_FBGT,A_FBGE,A_FBNGE,
+         A_FBLT,A_FBNLT,A_FBLE,A_FBGL,A_FBNGL,A_FBGLE,A_FBNGLE,
+         A_FDBEQ,A_FDBNE,A_FDBGT,A_FDBNGT,A_FDBGE,A_FDBNGE,
+         A_FDBLT,A_FDBNLT,A_FDBLE,A_FDBGL,A_FDBNGL,A_FDBGLE,A_FBDNGLE,
+         A_FSEQ,A_FSNE,A_FSGT,A_FSNGT,A_FSGE,A_FSNGE,
+         A_FSLT,A_FSNLT,A_FSLE,A_FSGL,A_FSNGL,A_FSGLE,A_FSNGLE,
+         A_FCMP,A_FDIV,A_FMOVE,A_FMOVEM,
+         A_FMUL,A_FNEG,A_FNOP,A_FSQRT,A_FSUB,A_FSGLDIV,
+         A_FSFLMUL,A_FTST,
+         A_FTRAPEQ,A_FTRAPNE,A_FTRAPGT,A_FTRAPNGT,A_FTRAPGE,A_FTRAPNGE,
+         A_FTRAPLT,A_FTRAPNLT,A_FTRAPLE,A_FTRAPGL,A_FTRAPNGL,A_FTRAPGLE,A_FTRAPNGLE,
+         { Protected instructions }
+         A_CPRESTORE,A_CPSAVE,
+         { FPU Unit protected instructions                    }
+         { and 68030/68851 common MMU instructions            }
+         { (this may include 68040 MMU instructions)          }
+         A_FRESTORE,A_FSAVE,A_PFLUSH,A_PFLUSHA,A_PLOAD,A_PMOVE,A_PTEST,
+         { Useful for assembly langage output }
+         A_LABEL,A_NONE);
+
+
+Function X(y:myenum): myenum;
+Begin
+ x:=y;
+end;
+
+
+Procedure SecondInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op,op2 : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_IN_BYTE:');
+ oplist:=[];
+ op:=A_JSR;
+ if A_JSR in oplist then
+  begin
+    WriteLn('A_JSR in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('A_JSR in [] PASSED.');
+ if op in oplist then
+  begin
+    WriteLn('op(A_JSR) in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('op (A_JSR) in [] PASSED.');
+ op:=A_MOVE;
+ oplist:=oplist+[A_MOVE];
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+ if op in oplist then
+  WriteLn('op(A_MOVE) in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('op(A_MOVE) in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+  op:=A_MOVE;
+  oplist:=[];
+  oplist:=[A_SUB]+[op];
+  op2:=A_MOVE;
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+ if op2 in oplist then
+  WriteLn('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSetByte;
+{ SET_SET_BYTE }
+var
+ op : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_SET_BYTE(1):');
+ op:=A_LABEL;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true
+ end;
+ Write('TESTING INCLUDE:');
+ op:=A_RTE;
+ include(oplist,op);
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SetAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_LABEL];
+ oplist:=op2list+oplist;
+ if A_MOVE in oplist then
+  if A_LABEL in oplist then
+   if A_JSR in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+ else
+  begin
+    WriteLn('TESTING SET_ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ oplist:=op2list-oplist;
+ if (A_MOVE in oplist) or (A_LABEL in oplist) or (A_JSR in oplist) then
+   begin
+    WriteLn('TESTING SET_SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_SUB_SETS: PASSED.');
+ oplist := [A_MOVE,A_RTE];
+ exclude(oplist,A_MOVE);
+ if (A_MOVE in oplist) then
+  begin
+    WriteLn('TESTING EXCLUDE: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING EXCLUDE: PASSED.')
+end;
+
+Procedure SetCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ if oplist=op2list then
+  WriteLn('TESTING SET_COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[A_MOVE];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING SET_COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_COMP_SETS(2): PASSED.');
+end;
+
+Procedure SetMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE];
+ oplist:=oplist*op2list;
+ if A_JSR in oplist then
+  begin
+    WriteLn('TESTING SET_MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_MUL_SETS(1): PASSED.');
+ if A_MOVE in oplist  then
+  WriteLn('TESTING SET_MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+{------------------------------ TESTS FOR SMALL VALUES ---------------------}
+Procedure SmallInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING IN_BYTE:');
+ oplist:=[];
+ op:=Dn;
+ if op in oplist then
+  begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+ op:=dm;
+ oplist:=oplist+[Dm];
+ if op in oplist then
+  WriteLn(' PASSED.')
+ else
+   begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSetByte;
+{ SET_SET_BYTE }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING SET_BYTE(1):');
+ op:=DA;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SmallAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DB];
+ oplist:=op2list+oplist;
+ if DA in oplist then
+  if DC in oplist then
+   if DB in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+   begin
+     WriteLn('TESTING ADD_SETS: FAILED.');
+     failed := true
+   end
+ else
+  begin
+    WriteLn('TESTING ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ oplist:=op2list-oplist;
+ if (DA in oplist) or (DB in oplist) or (DC in oplist) then
+  begin
+    WriteLn('TESTING SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SUB_SETS: PASSED.')
+end;
+
+Procedure SmallCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ if oplist=op2list then
+  WriteLn('TESTING COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[DA];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING COMP_SETS(2): PASSED.');
+end;
+
+Procedure SmallMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA];
+ oplist:=oplist*op2list;
+ if DC in oplist then
+  begin
+    WriteLn('TESTING MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING MUL_SETS(1): PASSED.');
+ if DA in oplist  then
+  WriteLn('TESTING MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+const
+ b: myenum = (dA);
+var
+ enum: set of myenum;
+ oplist: set of tasmop;
+ l : word;
+Begin
+{ small sets }
+ enum:=[];
+ { add }
+ enum:=enum+[da];
+ { subtract }
+ enum:=enum-[da];
+ if DA in enum then
+  WriteLn('Found A_LABEL');
+ { very large sets       }
+ { copy loop test        }
+ WRITELN('LARGE SETS:');
+ oplist := [A_LABEL];
+ { secondin test         }
+ if A_LABEL in oplist then
+  WriteLn('TESTING SIMPLE SECOND_IN: PASSED.')
+ else
+   begin
+    failed := true
+  end;
+
+ { }
+ oplist:=[];
+ if A_LABEL in oplist then
+   begin
+    WriteLn('SECOND IN FAILED.');
+    failed := true
+  end;
+ SecondinSets;
+ SetSetByte;
+ SetAddSets;
+ SetSubSets;
+ SetCompSets;
+ SetMulSets;
+ WRITELN('SMALL SETS:');
+ SmallInSets;
+ SmallAddSets;
+ SmallSubSets;
+ SmallCompSets;
+ SmallMulSets;
+ l:=word(A_CPRESTORE);
+ if l = word(A_CPRESTORE) then
+  Begin
+  end
+  else failed := true;
+
+  if failed then
+    begin
+      WriteLn('One or more test failed');
+      Halt(1);
+    end;
+end.

+ 492 - 0
tests/test/tset2c.pp

@@ -0,0 +1,492 @@
+(*********************************************************************)
+(* Copyright (C) 1998, Carl Eric Codere                              *)
+(*********************************************************************)
+(* FPC (Free Pascal compiler) testsuite: SETS                        *)
+(*   Tests the following: in, +, -, *, assignments.                  *)
+(*      for small sets amd large sets, both with constants           *)
+(*      and variables.                                               *)
+(*********************************************************************)
+
+{$packset 1}
+
+const
+  failed: boolean = false;
+
+type
+       myenum = (dA:=17,dB,dC,dd,dedf,dg,dh,di,dj,dk,dl,dm,dn);
+       tasmop = (A_ABCD:=21,
+         A_ADD,A_ADDA,A_ADDI,A_ADDQ,A_ADDX,A_AND,A_ANDI,
+         A_ASL,A_ASR,A_BCC,A_BCS,A_BEQ,A_BGE,A_BGT,A_BHI,
+         A_BLE,A_BLS,A_BLT,A_BMI,A_BNE,A_BPL,A_BVC,A_BVS,
+         A_BCHG,A_BCLR,A_BRA,A_BSET,A_BSR,A_BTST,A_CHK,
+         A_CLR,A_CMP,A_CMPA,A_CMPI,A_CMPM,A_DBCC,A_DBCS,A_DBEQ,A_DBGE,
+         A_DBGT,A_DBHI,A_DBLE,A_DBLS,A_DBLT,A_DBMI,A_DBNE,A_DBRA,
+         A_DBPL,A_DBT,A_DBVC,A_DBVS,A_DBF,A_DIVS,A_DIVU,
+         A_EOR,A_EORI,A_EXG,A_ILLEGAL,A_EXT,A_JMP,A_JSR,
+         A_LEA,A_LINK,A_LSL,A_LSR,A_MOVE,A_MOVEA,A_MOVEI,A_MOVEQ,
+         A_MOVEM,A_MOVEP,A_MULS,A_MULU,A_NBCD,A_NEG,A_NEGX,
+         A_NOP,A_NOT,A_OR,A_ORI,A_PEA,A_ROL,A_ROR,A_ROXL,
+         A_ROXR,A_RTR,A_RTS,A_SBCD,A_SCC,A_SCS,A_SEQ,A_SGE,
+         A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,A_SNE,
+         A_SPL,A_ST,A_SVC,A_SVS,A_SF,A_SUB,A_SUBA,A_SUBI,A_SUBQ,
+         A_SUBX,A_SWAP,A_TAS,A_TRAP,A_TRAPV,A_TST,A_UNLK,
+         A_RTE,A_RESET,A_STOP,
+         { MC68010 instructions }
+         A_BKPT,A_MOVEC,A_MOVES,A_RTD,
+         { MC68020 instructions }
+         A_BFCHG,A_BFCLR,A_BFEXTS,A_BFEXTU,A_BFFFO,
+         A_BFINS,A_BFSET,A_BFTST,A_CALLM,A_CAS,A_CAS2,
+         A_CHK2,A_CMP2,A_DIVSL,A_DIVUL,A_EXTB,A_PACK,A_RTM,
+         A_TRAPCC,A_TRACS,A_TRAPEQ,A_TRAPF,A_TRAPGE,A_TRAPGT,
+         A_TRAPHI,A_TRAPLE,A_TRAPLS,A_TRAPLT,A_TRAPMI,A_TRAPNE,
+         A_TRAPPL,A_TRAPT,A_TRAPVC,A_TRAPVS,A_UNPK,
+         { FPU Processor instructions - directly supported only. }
+         { IEEE aware and misc. condition codes not supported   }
+         A_FABS,A_FADD,
+         A_FBEQ,A_FBNE,A_FBNGT,A_FBGT,A_FBGE,A_FBNGE,
+         A_FBLT,A_FBNLT,A_FBLE,A_FBGL,A_FBNGL,A_FBGLE,A_FBNGLE,
+         A_FDBEQ,A_FDBNE,A_FDBGT,A_FDBNGT,A_FDBGE,A_FDBNGE,
+         A_FDBLT,A_FDBNLT,A_FDBLE,A_FDBGL,A_FDBNGL,A_FDBGLE,A_FBDNGLE,
+         A_FSEQ,A_FSNE,A_FSGT,A_FSNGT,A_FSGE,A_FSNGE,
+         A_FSLT,A_FSNLT,A_FSLE,A_FSGL,A_FSNGL,A_FSGLE,A_FSNGLE,
+         A_FCMP,A_FDIV,A_FMOVE,A_FMOVEM,
+         A_FMUL,A_FNEG,A_FNOP,A_FSQRT,A_FSUB,A_FSGLDIV,
+         A_FSFLMUL,A_FTST,
+         A_FTRAPEQ,A_FTRAPNE,A_FTRAPGT,A_FTRAPNGT,A_FTRAPGE,A_FTRAPNGE,
+         A_FTRAPLT,A_FTRAPNLT,A_FTRAPLE,A_FTRAPGL,A_FTRAPNGL,A_FTRAPGLE,A_FTRAPNGLE,
+         { Protected instructions }
+         A_CPRESTORE,A_CPSAVE,
+         { FPU Unit protected instructions                    }
+         { and 68030/68851 common MMU instructions            }
+         { (this may include 68040 MMU instructions)          }
+         A_FRESTORE,A_FSAVE,A_PFLUSH,A_PFLUSHA,A_PLOAD,A_PMOVE,A_PTEST,
+         { Useful for assembly langage output }
+         A_LABEL,A_NONE);
+
+
+Function X(y:myenum): myenum;
+Begin
+ x:=y;
+end;
+
+
+Procedure SecondInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op,op2 : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_IN_BYTE:');
+ oplist:=[];
+ op:=A_JSR;
+ if A_JSR in oplist then
+  begin
+    WriteLn('A_JSR in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('A_JSR in [] PASSED.');
+ if op in oplist then
+  begin
+    WriteLn('op(A_JSR) in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('op (A_JSR) in [] PASSED.');
+ op:=A_MOVE;
+ oplist:=oplist+[A_MOVE];
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+ if op in oplist then
+  WriteLn('op(A_MOVE) in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('op(A_MOVE) in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+  op:=A_MOVE;
+  oplist:=[];
+  oplist:=[A_SUB]+[op];
+  op2:=A_MOVE;
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+ if op2 in oplist then
+  WriteLn('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSetByte;
+{ SET_SET_BYTE }
+var
+ op : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_SET_BYTE(1):');
+ op:=A_LABEL;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true
+ end;
+ Write('TESTING INCLUDE:');
+ op:=A_RTE;
+ include(oplist,op);
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SetAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_LABEL];
+ oplist:=op2list+oplist;
+ if A_MOVE in oplist then
+  if A_LABEL in oplist then
+   if A_JSR in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+ else
+  begin
+    WriteLn('TESTING SET_ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ oplist:=op2list-oplist;
+ if (A_MOVE in oplist) or (A_LABEL in oplist) or (A_JSR in oplist) then
+   begin
+    WriteLn('TESTING SET_SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_SUB_SETS: PASSED.');
+ oplist := [A_MOVE,A_RTE];
+ exclude(oplist,A_MOVE);
+ if (A_MOVE in oplist) then
+  begin
+    WriteLn('TESTING EXCLUDE: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING EXCLUDE: PASSED.')
+end;
+
+Procedure SetCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ if oplist=op2list then
+  WriteLn('TESTING SET_COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[A_MOVE];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING SET_COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_COMP_SETS(2): PASSED.');
+end;
+
+Procedure SetMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE];
+ oplist:=oplist*op2list;
+ if A_JSR in oplist then
+  begin
+    WriteLn('TESTING SET_MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_MUL_SETS(1): PASSED.');
+ if A_MOVE in oplist  then
+  WriteLn('TESTING SET_MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+{------------------------------ TESTS FOR SMALL VALUES ---------------------}
+Procedure SmallInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING IN_BYTE:');
+ oplist:=[];
+ op:=Dn;
+ if op in oplist then
+  begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+ op:=dm;
+ oplist:=oplist+[Dm];
+ if op in oplist then
+  WriteLn(' PASSED.')
+ else
+   begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSetByte;
+{ SET_SET_BYTE }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING SET_BYTE(1):');
+ op:=DA;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SmallAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DB];
+ oplist:=op2list+oplist;
+ if DA in oplist then
+  if DC in oplist then
+   if DB in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+   begin
+     WriteLn('TESTING ADD_SETS: FAILED.');
+     failed := true
+   end
+ else
+  begin
+    WriteLn('TESTING ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ oplist:=op2list-oplist;
+ if (DA in oplist) or (DB in oplist) or (DC in oplist) then
+  begin
+    WriteLn('TESTING SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SUB_SETS: PASSED.')
+end;
+
+Procedure SmallCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ if oplist=op2list then
+  WriteLn('TESTING COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[DA];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING COMP_SETS(2): PASSED.');
+end;
+
+Procedure SmallMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA];
+ oplist:=oplist*op2list;
+ if DC in oplist then
+  begin
+    WriteLn('TESTING MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING MUL_SETS(1): PASSED.');
+ if DA in oplist  then
+  WriteLn('TESTING MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+const
+ b: myenum = (dA);
+var
+ enum: set of myenum;
+ oplist: set of tasmop;
+ l : word;
+Begin
+{ small sets }
+ enum:=[];
+ { add }
+ enum:=enum+[da];
+ { subtract }
+ enum:=enum-[da];
+ if DA in enum then
+  WriteLn('Found A_LABEL');
+ { very large sets       }
+ { copy loop test        }
+ WRITELN('LARGE SETS:');
+ oplist := [A_LABEL];
+ { secondin test         }
+ if A_LABEL in oplist then
+  WriteLn('TESTING SIMPLE SECOND_IN: PASSED.')
+ else
+   begin
+    failed := true
+  end;
+
+ { }
+ oplist:=[];
+ if A_LABEL in oplist then
+   begin
+    WriteLn('SECOND IN FAILED.');
+    failed := true
+  end;
+ SecondinSets;
+ SetSetByte;
+ SetAddSets;
+ SetSubSets;
+ SetCompSets;
+ SetMulSets;
+ WRITELN('SMALL SETS:');
+ SmallInSets;
+ SmallAddSets;
+ SmallSubSets;
+ SmallCompSets;
+ SmallMulSets;
+ l:=word(A_CPRESTORE);
+ if l = word(A_CPRESTORE) then
+  Begin
+  end
+  else failed := true;
+
+  if failed then
+    begin
+      WriteLn('One or more test failed');
+      Halt(1);
+    end;
+end.

+ 492 - 0
tests/test/tset2d.pp

@@ -0,0 +1,492 @@
+(*********************************************************************)
+(* Copyright (C) 1998, Carl Eric Codere                              *)
+(*********************************************************************)
+(* FPC (Free Pascal compiler) testsuite: SETS                        *)
+(*   Tests the following: in, +, -, *, assignments.                  *)
+(*      for small sets amd large sets, both with constants           *)
+(*      and variables.                                               *)
+(*********************************************************************)
+
+{$packset 2}
+
+const
+  failed: boolean = false;
+
+type
+       myenum = (dA:=17,dB,dC,dd,dedf,dg,dh,di,dj,dk,dl,dm,dn);
+       tasmop = (A_ABCD:=21,
+         A_ADD,A_ADDA,A_ADDI,A_ADDQ,A_ADDX,A_AND,A_ANDI,
+         A_ASL,A_ASR,A_BCC,A_BCS,A_BEQ,A_BGE,A_BGT,A_BHI,
+         A_BLE,A_BLS,A_BLT,A_BMI,A_BNE,A_BPL,A_BVC,A_BVS,
+         A_BCHG,A_BCLR,A_BRA,A_BSET,A_BSR,A_BTST,A_CHK,
+         A_CLR,A_CMP,A_CMPA,A_CMPI,A_CMPM,A_DBCC,A_DBCS,A_DBEQ,A_DBGE,
+         A_DBGT,A_DBHI,A_DBLE,A_DBLS,A_DBLT,A_DBMI,A_DBNE,A_DBRA,
+         A_DBPL,A_DBT,A_DBVC,A_DBVS,A_DBF,A_DIVS,A_DIVU,
+         A_EOR,A_EORI,A_EXG,A_ILLEGAL,A_EXT,A_JMP,A_JSR,
+         A_LEA,A_LINK,A_LSL,A_LSR,A_MOVE,A_MOVEA,A_MOVEI,A_MOVEQ,
+         A_MOVEM,A_MOVEP,A_MULS,A_MULU,A_NBCD,A_NEG,A_NEGX,
+         A_NOP,A_NOT,A_OR,A_ORI,A_PEA,A_ROL,A_ROR,A_ROXL,
+         A_ROXR,A_RTR,A_RTS,A_SBCD,A_SCC,A_SCS,A_SEQ,A_SGE,
+         A_SGT,A_SHI,A_SLE,A_SLS,A_SLT,A_SMI,A_SNE,
+         A_SPL,A_ST,A_SVC,A_SVS,A_SF,A_SUB,A_SUBA,A_SUBI,A_SUBQ,
+         A_SUBX,A_SWAP,A_TAS,A_TRAP,A_TRAPV,A_TST,A_UNLK,
+         A_RTE,A_RESET,A_STOP,
+         { MC68010 instructions }
+         A_BKPT,A_MOVEC,A_MOVES,A_RTD,
+         { MC68020 instructions }
+         A_BFCHG,A_BFCLR,A_BFEXTS,A_BFEXTU,A_BFFFO,
+         A_BFINS,A_BFSET,A_BFTST,A_CALLM,A_CAS,A_CAS2,
+         A_CHK2,A_CMP2,A_DIVSL,A_DIVUL,A_EXTB,A_PACK,A_RTM,
+         A_TRAPCC,A_TRACS,A_TRAPEQ,A_TRAPF,A_TRAPGE,A_TRAPGT,
+         A_TRAPHI,A_TRAPLE,A_TRAPLS,A_TRAPLT,A_TRAPMI,A_TRAPNE,
+         A_TRAPPL,A_TRAPT,A_TRAPVC,A_TRAPVS,A_UNPK,
+         { FPU Processor instructions - directly supported only. }
+         { IEEE aware and misc. condition codes not supported   }
+         A_FABS,A_FADD,
+         A_FBEQ,A_FBNE,A_FBNGT,A_FBGT,A_FBGE,A_FBNGE,
+         A_FBLT,A_FBNLT,A_FBLE,A_FBGL,A_FBNGL,A_FBGLE,A_FBNGLE,
+         A_FDBEQ,A_FDBNE,A_FDBGT,A_FDBNGT,A_FDBGE,A_FDBNGE,
+         A_FDBLT,A_FDBNLT,A_FDBLE,A_FDBGL,A_FDBNGL,A_FDBGLE,A_FBDNGLE,
+         A_FSEQ,A_FSNE,A_FSGT,A_FSNGT,A_FSGE,A_FSNGE,
+         A_FSLT,A_FSNLT,A_FSLE,A_FSGL,A_FSNGL,A_FSGLE,A_FSNGLE,
+         A_FCMP,A_FDIV,A_FMOVE,A_FMOVEM,
+         A_FMUL,A_FNEG,A_FNOP,A_FSQRT,A_FSUB,A_FSGLDIV,
+         A_FSFLMUL,A_FTST,
+         A_FTRAPEQ,A_FTRAPNE,A_FTRAPGT,A_FTRAPNGT,A_FTRAPGE,A_FTRAPNGE,
+         A_FTRAPLT,A_FTRAPNLT,A_FTRAPLE,A_FTRAPGL,A_FTRAPNGL,A_FTRAPGLE,A_FTRAPNGLE,
+         { Protected instructions }
+         A_CPRESTORE,A_CPSAVE,
+         { FPU Unit protected instructions                    }
+         { and 68030/68851 common MMU instructions            }
+         { (this may include 68040 MMU instructions)          }
+         A_FRESTORE,A_FSAVE,A_PFLUSH,A_PFLUSHA,A_PLOAD,A_PMOVE,A_PTEST,
+         { Useful for assembly langage output }
+         A_LABEL,A_NONE);
+
+
+Function X(y:myenum): myenum;
+Begin
+ x:=y;
+end;
+
+
+Procedure SecondInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op,op2 : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_IN_BYTE:');
+ oplist:=[];
+ op:=A_JSR;
+ if A_JSR in oplist then
+  begin
+    WriteLn('A_JSR in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('A_JSR in [] PASSED.');
+ if op in oplist then
+  begin
+    WriteLn('op(A_JSR) in [] FAILED.');
+    failed := true
+  end
+ else
+  Writeln('op (A_JSR) in [] PASSED.');
+ op:=A_MOVE;
+ oplist:=oplist+[A_MOVE];
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+ if op in oplist then
+  WriteLn('op(A_MOVE) in ([]+[A_MOVE]) PASSED.')
+ else
+  begin
+    Writeln('op(A_MOVE) in ([]+[A_MOVE]) FAILED.');
+    failed := true;
+  end;
+  op:=A_MOVE;
+  oplist:=[];
+  oplist:=[A_SUB]+[op];
+  op2:=A_MOVE;
+ if A_MOVE in oplist then
+  WriteLn('A_MOVE in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('A_MOVE in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+ if op2 in oplist then
+  WriteLn('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) PASSED.')
+ else
+  begin
+    Writeln('op2(A_MOVE) in ([A_SUB]+[op(A_MOVE)]) FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSetByte;
+{ SET_SET_BYTE }
+var
+ op : tasmop;
+ oplist: set of tasmop;
+Begin
+ Write('TESTING SET_SET_BYTE(1):');
+ op:=A_LABEL;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true
+ end;
+ Write('TESTING INCLUDE:');
+ op:=A_RTE;
+ include(oplist,op);
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SetAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_LABEL];
+ oplist:=op2list+oplist;
+ if A_MOVE in oplist then
+  if A_LABEL in oplist then
+   if A_JSR in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+    begin
+      WriteLn('TESTING SET_ADD_SETS: FAILED.');
+      failed := true
+    end
+ else
+  begin
+    WriteLn('TESTING SET_ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SetSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ oplist:=op2list-oplist;
+ if (A_MOVE in oplist) or (A_LABEL in oplist) or (A_JSR in oplist) then
+   begin
+    WriteLn('TESTING SET_SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_SUB_SETS: PASSED.');
+ oplist := [A_MOVE,A_RTE];
+ exclude(oplist,A_MOVE);
+ if (A_MOVE in oplist) then
+  begin
+    WriteLn('TESTING EXCLUDE: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING EXCLUDE: PASSED.')
+end;
+
+Procedure SetCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE]+[A_JSR];
+ if oplist=op2list then
+  WriteLn('TESTING SET_COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[A_MOVE];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING SET_COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_COMP_SETS(2): PASSED.');
+end;
+
+Procedure SetMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of tasmop;
+ oplist: set of tasmop;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[A_MOVE]+[A_JSR];
+ op2list:=[A_MOVE];
+ oplist:=oplist*op2list;
+ if A_JSR in oplist then
+  begin
+    WriteLn('TESTING SET_MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SET_MUL_SETS(1): PASSED.');
+ if A_MOVE in oplist  then
+  WriteLn('TESTING SET_MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING SET_MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+{------------------------------ TESTS FOR SMALL VALUES ---------------------}
+Procedure SmallInSets;
+{ SET_IN_BYTE TESTS }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING IN_BYTE:');
+ oplist:=[];
+ op:=Dn;
+ if op in oplist then
+  begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+ op:=dm;
+ oplist:=oplist+[Dm];
+ if op in oplist then
+  WriteLn(' PASSED.')
+ else
+   begin
+    WriteLn(' FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSetByte;
+{ SET_SET_BYTE }
+var
+ op : myenum;
+ oplist: set of myenum;
+Begin
+ Write('TESTING SET_BYTE(1):');
+ op:=DA;
+ oplist:=[];
+ oplist:=oplist+[op];
+ if op in oplist then
+ Begin
+  WriteLn(' PASSED.');
+ end
+ else
+ Begin
+  WriteLn(' FAILED.');
+  failed := true;
+ end;
+end;
+
+
+Procedure SmallAddSets;
+{ SET_ADD_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DB];
+ oplist:=op2list+oplist;
+ if DA in oplist then
+  if DC in oplist then
+   if DB in oplist then
+    WriteLn('TESTING SET_ADD_SETS: PASSED.')
+   else
+    begin
+      WriteLn('TESTING ADD_SETS: FAILED.');
+      failed := true
+    end
+  else
+   begin
+     WriteLn('TESTING ADD_SETS: FAILED.');
+     failed := true
+   end
+ else
+  begin
+    WriteLn('TESTING ADD_SETS: FAILED.');
+    failed := true
+  end;
+end;
+
+Procedure SmallSubsets;
+{ SET_SUB_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ oplist:=op2list-oplist;
+ if (DA in oplist) or (DB in oplist) or (DC in oplist) then
+  begin
+    WriteLn('TESTING SUB_SETS: FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING SUB_SETS: PASSED.')
+end;
+
+Procedure SmallCompSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA]+[DC];
+ if oplist=op2list then
+  WriteLn('TESTING COMP_SETS(1): PASSED.')
+ else
+  begin
+    WriteLn('TESTING COMP_SETS(1): FAILED.');
+    failed := true
+  end;
+ oplist:=[DA];
+ if oplist=op2list then
+  begin
+    WriteLn('TESTING COMP_SETS(2): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING COMP_SETS(2): PASSED.');
+end;
+
+Procedure SmallMulSets;
+{ SET_COMP_SETS }
+var
+ op2list :set of myenum;
+ oplist: set of myenum;
+Begin
+ op2list:=[];
+ oplist:=[];
+ oplist:=[DA]+[DC];
+ op2list:=[DA];
+ oplist:=oplist*op2list;
+ if DC in oplist then
+  begin
+    WriteLn('TESTING MUL_SETS(1): FAILED.');
+    failed := true
+  end
+ else
+  WriteLn('TESTING MUL_SETS(1): PASSED.');
+ if DA in oplist  then
+  WriteLn('TESTING MUL_SETS(2): PASSED.')
+ else
+  begin
+    WriteLn('TESTING MUL_SETS(2): FAILED.');
+    failed := true
+  end;
+end;
+
+const
+ b: myenum = (dA);
+var
+ enum: set of myenum;
+ oplist: set of tasmop;
+ l : word;
+Begin
+{ small sets }
+ enum:=[];
+ { add }
+ enum:=enum+[da];
+ { subtract }
+ enum:=enum-[da];
+ if DA in enum then
+  WriteLn('Found A_LABEL');
+ { very large sets       }
+ { copy loop test        }
+ WRITELN('LARGE SETS:');
+ oplist := [A_LABEL];
+ { secondin test         }
+ if A_LABEL in oplist then
+  WriteLn('TESTING SIMPLE SECOND_IN: PASSED.')
+ else
+   begin
+    failed := true
+  end;
+
+ { }
+ oplist:=[];
+ if A_LABEL in oplist then
+   begin
+    WriteLn('SECOND IN FAILED.');
+    failed := true
+  end;
+ SecondinSets;
+ SetSetByte;
+ SetAddSets;
+ SetSubSets;
+ SetCompSets;
+ SetMulSets;
+ WRITELN('SMALL SETS:');
+ SmallInSets;
+ SmallAddSets;
+ SmallSubSets;
+ SmallCompSets;
+ SmallMulSets;
+ l:=word(A_CPRESTORE);
+ if l = word(A_CPRESTORE) then
+  Begin
+  end
+  else failed := true;
+
+  if failed then
+    begin
+      WriteLn('One or more test failed');
+      Halt(1);
+    end;
+end.

+ 234 - 0
tests/test/tsetsize.pp

@@ -0,0 +1,234 @@
+program SetSizes;
+
+{$APPTYPE CONSOLE}
+
+{$ifdef fpc}
+  {$mode delphi}
+  {$packset 1}
+{$endif}
+
+const
+  _a= 0;
+
+type
+  TIntRange1_a =  0 + _a.. Pred( 1 * 8) + _a;
+  TIntRange2_a =  0 + _a.. Pred( 2 * 8) + _a;
+  TIntRange3_a =  0 + _a.. Pred( 3 * 8) + _a;
+  TIntRange4_a =  0 + _a.. Pred( 4 * 8) + _a;
+  TIntRange5_a =  0 + _a.. Pred( 5 * 8) + _a;
+  TIntRange6_a =  0 + _a.. Pred( 6 * 8) + _a;
+  TIntRange7_a =  0 + _a.. Pred( 7 * 8) + _a;
+  TIntRange8_a =  0 + _a.. Pred( 8 * 8) + _a;
+  TIntRange9_a =  0 + _a.. Pred( 9 * 8) + _a;
+  TIntRange10_a=  0 + _a.. Pred(10 * 8) + _a;
+  TIntRange11_a=  0 + _a.. Pred(11 * 8) + _a;
+  TIntRange12_a=  0 + _a.. Pred(12 * 8) + _a;
+  TIntRange13_a=  0 + _a.. Pred(13 * 8) + _a;
+  TIntRange14_a=  0 + _a.. Pred(14 * 8) + _a;
+  TIntRange15_a=  0 + _a.. Pred(15 * 8) + _a;
+  TIntRange16_a=  0 + _a.. Pred(16 * 8) + _a;
+
+  TSet1_a = set of TIntRange1_a;
+  TSet2_a = set of TIntRange2_a;
+  TSet3_a = set of TIntRange3_a;
+  TSet4_a = set of TIntRange4_a;
+  TSet5_a = set of TIntRange5_a;
+  TSet6_a = set of TIntRange6_a;
+  TSet7_a = set of TIntRange7_a;
+  TSet8_a = set of TIntRange8_a;
+  TSet9_a = set of TIntRange9_a;
+  TSet10_a= set of TIntRange10_a;
+  TSet11_a= set of TIntRange11_a;
+  TSet12_a= set of TIntRange12_a;
+  TSet13_a= set of TIntRange13_a;
+  TSet14_a= set of TIntRange14_a;
+  TSet15_a= set of TIntRange15_a;
+  TSet16_a= set of TIntRange16_a;
+
+const
+  _b= 1;
+
+type
+  TIntRange1_b =  0 + _b.. Pred( 1 * 8) + _b;
+  TIntRange2_b =  0 + _b.. Pred( 2 * 8) + _b;
+  TIntRange3_b =  0 + _b.. Pred( 3 * 8) + _b;
+  TIntRange4_b =  0 + _b.. Pred( 4 * 8) + _b;
+  TIntRange5_b =  0 + _b.. Pred( 5 * 8) + _b;
+  TIntRange6_b =  0 + _b.. Pred( 6 * 8) + _b;
+  TIntRange7_b =  0 + _b.. Pred( 7 * 8) + _b;
+  TIntRange8_b =  0 + _b.. Pred( 8 * 8) + _b;
+  TIntRange9_b =  0 + _b.. Pred( 9 * 8) + _b;
+  TIntRange10_b=  0 + _b.. Pred(10 * 8) + _b;
+  TIntRange11_b=  0 + _b.. Pred(11 * 8) + _b;
+  TIntRange12_b=  0 + _b.. Pred(12 * 8) + _b;
+  TIntRange13_b=  0 + _b.. Pred(13 * 8) + _b;
+  TIntRange14_b=  0 + _b.. Pred(14 * 8) + _b;
+  TIntRange15_b=  0 + _b.. Pred(15 * 8) + _b;
+  TIntRange16_b=  0 + _b.. Pred(16 * 8) + _b;
+
+  TSet1_b = set of TIntRange1_b;
+  TSet2_b = set of TIntRange2_b;
+  TSet3_b = set of TIntRange3_b;
+  TSet4_b = set of TIntRange4_b;
+  TSet5_b = set of TIntRange5_b;
+  TSet6_b = set of TIntRange6_b;
+  TSet7_b = set of TIntRange7_b;
+  TSet8_b = set of TIntRange8_b;
+  TSet9_b = set of TIntRange9_b;
+  TSet10_b= set of TIntRange10_b;
+  TSet11_b= set of TIntRange11_b;
+  TSet12_b= set of TIntRange12_b;
+  TSet13_b= set of TIntRange13_b;
+  TSet14_b= set of TIntRange14_b;
+  TSet15_b= set of TIntRange15_b;
+  TSet16_b= set of TIntRange16_b;
+
+const
+  _c= 7;
+
+type
+  TIntRange1_c =  0 + _c.. Pred( 1 * 8) + _c;
+  TIntRange2_c =  0 + _c.. Pred( 2 * 8) + _c;
+  TIntRange3_c =  0 + _c.. Pred( 3 * 8) + _c;
+  TIntRange4_c =  0 + _c.. Pred( 4 * 8) + _c;
+  TIntRange5_c =  0 + _c.. Pred( 5 * 8) + _c;
+  TIntRange6_c =  0 + _c.. Pred( 6 * 8) + _c;
+  TIntRange7_c =  0 + _c.. Pred( 7 * 8) + _c;
+  TIntRange8_c =  0 + _c.. Pred( 8 * 8) + _c;
+  TIntRange9_c =  0 + _c.. Pred( 9 * 8) + _c;
+  TIntRange10_c=  0 + _c.. Pred(10 * 8) + _c;
+  TIntRange11_c=  0 + _c.. Pred(11 * 8) + _c;
+  TIntRange12_c=  0 + _c.. Pred(12 * 8) + _c;
+  TIntRange13_c=  0 + _c.. Pred(13 * 8) + _c;
+  TIntRange14_c=  0 + _c.. Pred(14 * 8) + _c;
+  TIntRange15_c=  0 + _c.. Pred(15 * 8) + _c;
+  TIntRange16_c=  0 + _c.. Pred(16 * 8) + _c;
+
+  TSet1_c = set of TIntRange1_c;
+  TSet2_c = set of TIntRange2_c;
+  TSet3_c = set of TIntRange3_c;
+  TSet4_c = set of TIntRange4_c;
+  TSet5_c = set of TIntRange5_c;
+  TSet6_c = set of TIntRange6_c;
+  TSet7_c = set of TIntRange7_c;
+  TSet8_c = set of TIntRange8_c;
+  TSet9_c = set of TIntRange9_c;
+  TSet10_c= set of TIntRange10_c;
+  TSet11_c= set of TIntRange11_c;
+  TSet12_c= set of TIntRange12_c;
+  TSet13_c= set of TIntRange13_c;
+  TSet14_c= set of TIntRange14_c;
+  TSet15_c= set of TIntRange15_c;
+  TSet16_c= set of TIntRange16_c;
+
+procedure test(actualsize, wantsize: longint);
+begin
+  if (actualsize<>wantsize) then
+    halt(1);
+end;
+
+
+begin
+  WriteLn(Low(TIntRange1_a),'..',High(TIntRange1_a),' -> ', SizeOf(TSet1_a));
+  test(SizeOf(TSet1_a),1);
+  WriteLn(Low(TIntRange2_a),'..',High(TIntRange2_a),' -> ', SizeOf(TSet2_a));
+  test(SizeOf(TSet2_a),2);
+  WriteLn(Low(TIntRange3_a),'..',High(TIntRange3_a),' -> ', SizeOf(TSet3_a));
+  test(SizeOf(TSet3_a),4);
+  WriteLn(Low(TIntRange4_a),'..',High(TIntRange4_a),' -> ', SizeOf(TSet4_a));
+  test(SizeOf(TSet4_a),4);
+  WriteLn(Low(TIntRange5_a),'..',High(TIntRange5_a),' -> ', SizeOf(TSet5_a));
+  test(SizeOf(TSet5_a),5);
+  WriteLn(Low(TIntRange6_a),'..',High(TIntRange6_a),' -> ', SizeOf(TSet6_a));
+  test(SizeOf(TSet6_a),6);
+  WriteLn(Low(TIntRange7_a),'..',High(TIntRange7_a),' -> ', SizeOf(TSet7_a));
+  test(SizeOf(TSet7_a),7);
+  WriteLn(Low(TIntRange8_a),'..',High(TIntRange8_a),' -> ', SizeOf(TSet8_a));
+  test(SizeOf(TSet8_a),8);
+  WriteLn(Low(TIntRange9_a),'..',High(TIntRange9_a),' -> ', SizeOf(TSet9_a));
+  test(SizeOf(TSet9_a),9);
+  WriteLn(Low(TIntRange10_a),'..',High(TIntRange10_a),' -> ', SizeOf(TSet10_a));
+  test(SizeOf(TSet10_a),10);
+  WriteLn(Low(TIntRange11_a),'..',High(TIntRange11_a),' -> ', SizeOf(TSet11_a));
+  test(SizeOf(TSet11_a),11);
+  WriteLn(Low(TIntRange12_a),'..',High(TIntRange12_a),' -> ', SizeOf(TSet12_a));
+  test(SizeOf(TSet12_a),12);
+  WriteLn(Low(TIntRange13_a),'..',High(TIntRange13_a),' -> ', SizeOf(TSet13_a));
+  test(SizeOf(TSet13_a),13);
+  WriteLn(Low(TIntRange14_a),'..',High(TIntRange14_a),' -> ', SizeOf(TSet14_a));
+  test(SizeOf(TSet14_a),14);
+  WriteLn(Low(TIntRange15_a),'..',High(TIntRange15_a),' -> ', SizeOf(TSet15_a));
+  test(SizeOf(TSet15_a),15);
+  WriteLn(Low(TIntRange16_a),'..',High(TIntRange16_a),' -> ', SizeOf(TSet16_a));
+  test(SizeOf(TSet16_a),16);
+
+  WriteLn;
+
+  WriteLn(Low(TIntRange1_b),'..',High(TIntRange1_b),' -> ', SizeOf(TSet1_b));
+  test(SizeOf(TSet1_b),2);
+  WriteLn(Low(TIntRange2_b),'..',High(TIntRange2_b),' -> ', SizeOf(TSet2_b));
+  test(SizeOf(TSet2_b),4);
+  WriteLn(Low(TIntRange3_b),'..',High(TIntRange3_b),' -> ', SizeOf(TSet3_b));
+  test(SizeOf(TSet3_b),4);
+  WriteLn(Low(TIntRange4_b),'..',High(TIntRange4_b),' -> ', SizeOf(TSet4_b));
+  test(SizeOf(TSet4_b),5);
+  WriteLn(Low(TIntRange5_b),'..',High(TIntRange5_b),' -> ', SizeOf(TSet5_b));
+  test(SizeOf(TSet5_b),6);
+  WriteLn(Low(TIntRange6_b),'..',High(TIntRange6_b),' -> ', SizeOf(TSet6_b));
+  test(SizeOf(TSet6_b),7);
+  WriteLn(Low(TIntRange7_b),'..',High(TIntRange7_b),' -> ', SizeOf(TSet7_b));
+  test(SizeOf(TSet7_b),8);
+  WriteLn(Low(TIntRange8_b),'..',High(TIntRange8_b),' -> ', SizeOf(TSet8_b));
+  test(SizeOf(TSet8_b),9);
+  WriteLn(Low(TIntRange9_b),'..',High(TIntRange9_b),' -> ', SizeOf(TSet9_b));
+  test(SizeOf(TSet9_b),10);
+  WriteLn(Low(TIntRange10_b),'..',High(TIntRange10_b),' -> ', SizeOf(TSet10_b));
+  test(SizeOf(TSet10_b),11);
+  WriteLn(Low(TIntRange11_b),'..',High(TIntRange11_b),' -> ', SizeOf(TSet11_b));
+  test(SizeOf(TSet11_b),12);
+  WriteLn(Low(TIntRange12_b),'..',High(TIntRange12_b),' -> ', SizeOf(TSet12_b));
+  test(SizeOf(TSet12_b),13);
+  WriteLn(Low(TIntRange13_b),'..',High(TIntRange13_b),' -> ', SizeOf(TSet13_b));
+  test(SizeOf(TSet13_b),14);
+  WriteLn(Low(TIntRange14_b),'..',High(TIntRange14_b),' -> ', SizeOf(TSet14_b));
+  test(SizeOf(TSet14_b),15);
+  WriteLn(Low(TIntRange15_b),'..',High(TIntRange15_b),' -> ', SizeOf(TSet15_b));
+  test(SizeOf(TSet15_b),16);
+  WriteLn(Low(TIntRange16_b),'..',High(TIntRange16_b),' -> ', SizeOf(TSet16_b));
+  test(SizeOf(TSet16_b),17);
+
+  WriteLn;
+
+  WriteLn(Low(TIntRange1_c),'..',High(TIntRange1_c),' -> ', SizeOf(TSet1_c));
+  test(SizeOf(TSet1_c),2);
+  WriteLn(Low(TIntRange2_c),'..',High(TIntRange2_c),' -> ', SizeOf(TSet2_c));
+  test(SizeOf(TSet2_c),4);
+  WriteLn(Low(TIntRange3_c),'..',High(TIntRange3_c),' -> ', SizeOf(TSet3_c));
+  test(SizeOf(TSet3_c),4);
+  WriteLn(Low(TIntRange4_c),'..',High(TIntRange4_c),' -> ', SizeOf(TSet4_c));
+  test(SizeOf(TSet4_c),5);
+  WriteLn(Low(TIntRange5_c),'..',High(TIntRange5_c),' -> ', SizeOf(TSet5_c));
+  test(SizeOf(TSet5_c),6);
+  WriteLn(Low(TIntRange6_c),'..',High(TIntRange6_c),' -> ', SizeOf(TSet6_c));
+  test(SizeOf(TSet6_c),7);
+  WriteLn(Low(TIntRange7_c),'..',High(TIntRange7_c),' -> ', SizeOf(TSet7_c));
+  test(SizeOf(TSet7_c),8);
+  WriteLn(Low(TIntRange8_c),'..',High(TIntRange8_c),' -> ', SizeOf(TSet8_c));
+  test(SizeOf(TSet8_c),9);
+  WriteLn(Low(TIntRange9_c),'..',High(TIntRange9_c),' -> ', SizeOf(TSet9_c));
+  test(SizeOf(TSet9_c),10);
+  WriteLn(Low(TIntRange10_c),'..',High(TIntRange10_c),' -> ', SizeOf(TSet10_c));
+  test(SizeOf(TSet10_c),11);
+  WriteLn(Low(TIntRange11_c),'..',High(TIntRange11_c),' -> ', SizeOf(TSet11_c));
+  test(SizeOf(TSet11_c),12);
+  WriteLn(Low(TIntRange12_c),'..',High(TIntRange12_c),' -> ', SizeOf(TSet12_c));
+  test(SizeOf(TSet12_c),13);
+  WriteLn(Low(TIntRange13_c),'..',High(TIntRange13_c),' -> ', SizeOf(TSet13_c));
+  test(SizeOf(TSet13_c),14);
+  WriteLn(Low(TIntRange14_c),'..',High(TIntRange14_c),' -> ', SizeOf(TSet14_c));
+  test(SizeOf(TSet14_c),15);
+  WriteLn(Low(TIntRange15_c),'..',High(TIntRange15_c),' -> ', SizeOf(TSet15_c));
+  test(SizeOf(TSet15_c),16);
+  WriteLn(Low(TIntRange16_c),'..',High(TIntRange16_c),' -> ', SizeOf(TSet16_c));
+  test(SizeOf(TSet16_c),17);
+end.

+ 1256 - 0
tests/webtbs/tw8258b.pp

@@ -0,0 +1,1256 @@
+program SetTests;
+
+{$APPTYPE CONSOLE}
+
+{$IFDEF FPC}
+  {$mode delphi}
+{$ENDIF}
+
+{$R+}
+{$Q+}
+
+uses
+  SysUtils;
+
+var
+  u8      : Byte;
+  s8      : ShortInt;
+  u16     : Word;
+  s16     : SmallInt;
+  u32     : LongWord;
+  s32     : LongInt;
+  u64     : QWord;
+  s64     : Int64;
+
+  LargeSet : set of 67..221;
+  SmallSet : set of 9..21;
+
+  Error    : Boolean;
+
+procedure CheckResult(const s: string; aIs, aExpected: Boolean); overload;
+begin
+  if aIs <> aExpected then begin
+    WriteLn(s, aIs, ' <> ', aExpected, '   * * * ERROR * * * ERROR * * * ERROR * * *');
+    Error := True;
+  end else
+    WriteLn(s, aIs);
+end;
+
+procedure CheckResult(const s: string; aIs: Boolean); overload;
+begin
+  WriteLn(s, aIs, ' <> EXCEPTION   * * * ERROR * * * ERROR * * * ERROR * * *');
+  Error := True;
+end;
+
+
+begin
+  Error := False;
+
+  WriteLn('--- Variable against constant set [0, 2, 8..20, 99..192] ---' );
+  WriteLn;
+
+  u8  := 100;
+  s8  := 100;
+  u16 := 100;
+  s16 := 100;
+  u32 := 100;
+  s32 := 100;
+  u64 := 100;
+  s64 := 100;
+
+  WriteLn('100, should be true');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20, 99..192], True);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20, 99..192], True);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], True);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], True);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], True);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], True);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], True);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], True);
+  WriteLn;
+
+  u8  := 98;
+  s8  := 98;
+  u16 := 98;
+  s16 := 98;
+  u32 := 98;
+  s32 := 98;
+  u64 := 98;
+  s64 := 98;
+
+  WriteLn('98, should be false');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20, 99..192], False);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], False);
+  WriteLn;
+
+  u8  := 193;
+//  s8  := 193;
+  u16 := 193;
+  s16 := 193;
+  u32 := 193;
+  s32 := 193;
+  u64 := 193;
+  s64 := 193;
+
+  WriteLn('193, should be false');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20, 99..192], False);
+//  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], False);
+  WriteLn;
+
+//  u8  := 256;
+//  s8  := 256;
+  u16 := 256;
+  s16 := 256;
+  u32 := 256;
+  s32 := 256;
+  u64 := 256;
+  s64 := 256;
+
+  WriteLn('256, should be false');
+//  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20, 99..192], False);
+//  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], False);
+  WriteLn;
+
+  u8  := High(u8);
+  s8  := High(s8);
+  u16 := High(u16);
+  s16 := High(s16);
+  u32 := High(u32);
+  s32 := High(s32);
+  u64 := High(u64);
+  s64 := High(s64);
+
+  WriteLn('High(type), s8 should be true, u64/s64 should cause range check');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20, 99..192], False);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20, 99..192], True);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False);
+  try
+    CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192]);
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+    CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  u8  := Low(u8);
+  s8  := Low(s8);
+  u16 := Low(u16);
+  s16 := Low(s16);
+  u32 := Low(u32);
+  s32 := Low(s32);
+  u64 := Low(u64);
+  s64 := Low(s64);
+
+  WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error');
+  CheckResult('u8  -> ',  u8 in [0, 2, 8..20, 99..192], True);
+  CheckResult('s8  -> ',  s8 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], True);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], True);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], True);
+
+  try
+    CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- Variable against set of byte with value [8..20, 68, 72..83, 99..192] ---' );
+  WriteLn;
+
+  LargeSet := [68, 72..83, 99..192];
+
+  u8  := 100;
+  s8  := 100;
+  u16 := 100;
+  s16 := 100;
+  u32 := 100;
+  s32 := 100;
+  u64 := 100;
+  s64 := 100;
+
+  WriteLn('100, should be true');
+  CheckResult(' u8 -> ',  u8 in LargeSet, True);
+  CheckResult(' s8 -> ',  s8 in LargeSet, True);
+  CheckResult('u16 -> ', u16 in LargeSet, True);
+  CheckResult('s16 -> ', s16 in LargeSet, True);
+  CheckResult('u32 -> ', u32 in LargeSet, True);
+  CheckResult('s32 -> ', s32 in LargeSet, True);
+  CheckResult('u64 -> ', u64 in LargeSet, True);
+  CheckResult('s64 -> ', s64 in LargeSet, True);
+  WriteLn;
+
+  u8  := 98;
+  s8  := 98;
+  u16 := 98;
+  s16 := 98;
+  u32 := 98;
+  s32 := 98;
+  u64 := 98;
+  s64 := 98;
+
+  WriteLn('98, should be false');
+  CheckResult(' u8 -> ',  u8 in LargeSet, False);
+  CheckResult(' s8 -> ',  s8 in LargeSet, False);
+  CheckResult('u16 -> ', u16 in LargeSet, False);
+  CheckResult('s16 -> ', s16 in LargeSet, False);
+  CheckResult('u32 -> ', u32 in LargeSet, False);
+  CheckResult('s32 -> ', s32 in LargeSet, False);
+  CheckResult('u64 -> ', u64 in LargeSet, False);
+  CheckResult('s64 -> ', s64 in LargeSet, False);
+  WriteLn;
+
+  u8  := 193;
+//  s8  := 193;
+  u16 := 193;
+  s16 := 193;
+  u32 := 193;
+  s32 := 193;
+  u64 := 193;
+  s64 := 193;
+
+  WriteLn('193, should be false');
+  CheckResult(' u8 -> ',  u8 in LargeSet, False);
+//  CheckResult(' s8 -> ',  s8 in LargeSet, False);
+  CheckResult('u16 -> ', u16 in LargeSet, False);
+  CheckResult('s16 -> ', s16 in LargeSet, False);
+  CheckResult('u32 -> ', u32 in LargeSet, False);
+  CheckResult('s32 -> ', s32 in LargeSet, False);
+  CheckResult('u64 -> ', u64 in LargeSet, False);
+  CheckResult('s64 -> ', s64 in LargeSet, False);
+  WriteLn;
+
+//  u8  := 256;
+//  s8  := 256;
+  u16 := 256;
+  s16 := 256;
+  u32 := 256;
+  s32 := 256;
+  u64 := 256;
+  s64 := 256;
+
+  WriteLn('256, should be false');
+//  CheckResult(' u8 -> ',  u8 in LargeSet, False);
+//  CheckResult(' s8 -> ',  s8 in LargeSet, False);
+  CheckResult('u16 -> ', u16 in LargeSet, False);
+  CheckResult('s16 -> ', s16 in LargeSet, False);
+  CheckResult('u32 -> ', u32 in LargeSet, False);
+  CheckResult('s32 -> ', s32 in LargeSet, False);
+  CheckResult('u64 -> ', u64 in LargeSet, False);
+  CheckResult('s64 -> ', s64 in LargeSet, False);
+  WriteLn;
+
+  u8  := High(u8);
+  s8  := High(s8);
+  u16 := High(u16);
+  s16 := High(s16);
+  u32 := High(u32);
+  s32 := High(s32);
+  u64 := High(u64);
+  s64 := High(s64);
+
+  WriteLn('High(type), s8 should be true, u64/s64 should cause range check');
+  CheckResult(' u8 -> ',  u8 in LargeSet, False);
+  CheckResult(' s8 -> ',  s8 in LargeSet, True);
+  CheckResult('u16 -> ', u16 in LargeSet, False);
+  CheckResult('s16 -> ', s16 in LargeSet, False);
+  CheckResult('u32 -> ', u32 in LargeSet, False);
+  CheckResult('s32 -> ', s32 in LargeSet, False);
+  try
+    CheckResult('u64 -> ', u64 in LargeSet);
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+    CheckResult('s64 -> ', s64 in LargeSet);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  u8  := Low(u8);
+  s8  := Low(s8);
+  u16 := Low(u16);
+  s16 := Low(s16);
+  u32 := Low(u32);
+  s32 := Low(s32);
+  u64 := Low(u64);
+  s64 := Low(s64);
+
+  WriteLn('Low(type), all false, except s64 -> range check error');
+  CheckResult('u8  -> ',  u8 in LargeSet, False);
+  CheckResult('s8  -> ',  s8 in LargeSet, False);
+  CheckResult('u16 -> ', u16 in LargeSet, False);
+  CheckResult('s16 -> ', s16 in LargeSet, False);
+  CheckResult('u32 -> ', u32 in LargeSet, False);
+  CheckResult('s32 -> ', s32 in LargeSet, False);
+  CheckResult('u64 -> ', u64 in LargeSet, False);
+
+  try
+    CheckResult('s64 -> ', s64 in LargeSet);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- constant value against constant set [0, 2, 8..20, 99..192] ---' );
+  WriteLn;
+
+  WriteLn('100, should be true');
+  CheckResult('100 -> ', 100 in [0, 2, 8..20, 99..192], True);
+  WriteLn;
+
+  WriteLn('98, should be false');
+  CheckResult(' 98 -> ', 98 in [0, 2, 8..20, 99..192], False);
+  WriteLn;
+
+  WriteLn('193, should be false');
+  CheckResult('193 -> ', 193 in [0, 2, 8..20, 99..192], False);
+  WriteLn;
+
+  WriteLn('256, should be false');
+  CheckResult('256 -> ', 256 in [0, 2, 8..20, 99..192], False);
+  WriteLn;
+
+  WriteLn('High(type), s8 should be true, u64/s64 should cause range check at compile time');
+  CheckResult(' u8 -> ', High(u8)  in [0, 2, 8..20, 99..192], False);
+  CheckResult(' s8 -> ', High(s8)  in [0, 2, 8..20, 99..192], True);
+  CheckResult('u16 -> ', High(u16) in [0, 2, 8..20, 99..192], False);
+  CheckResult('s16 -> ', High(s16) in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', High(u32) in [0, 2, 8..20, 99..192], False);
+  CheckResult('s32 -> ', High(s32) in [0, 2, 8..20, 99..192], False);
+  try
+//    CheckResult('u64 -> ', High(u64) in [0, 2, 8..20, 99..192]);
+    WriteLn('u64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+//    CheckResult('s64 -> ', High(s64) in [0, 2, 8..20, 99..192]);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error at compile time');
+  CheckResult('u8  -> ',  Low(u8) in [0, 2, 8..20, 99..192], True);
+  CheckResult('s8  -> ',  Low(s8) in [0, 2, 8..20, 99..192], False);
+  CheckResult('u16 -> ', Low(u16) in [0, 2, 8..20, 99..192], True);
+  CheckResult('s16 -> ', Low(s16) in [0, 2, 8..20, 99..192], False);
+  CheckResult('u32 -> ', Low(u32) in [0, 2, 8..20, 99..192], True);
+  CheckResult('s32 -> ', Low(s32) in [0, 2, 8..20, 99..192], False);
+  CheckResult('u64 -> ', Low(u64) in [0, 2, 8..20, 99..192], True);
+
+  try
+//    CheckResult('s64 -> ', Low(s64) in [0, 2, 8..20, 99..192]);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- constant value against set of byte with value [0, 2, 8..20, 99..192] ---' );
+  WriteLn;
+
+  LargeSet := [68, 72..83, 99..192];
+
+  WriteLn('100, should be true');
+  CheckResult('100 -> ', 100 in LargeSet, True);
+  WriteLn;
+
+  WriteLn('98, should be false');
+  CheckResult(' 98 -> ',  98 in LargeSet, False);
+  WriteLn;
+
+  WriteLn('193, should be false');
+  CheckResult('193 -> ', 193 in LargeSet, False);
+  WriteLn;
+
+  WriteLn('256, should be false');
+  CheckResult('256 -> ', 256 in LargeSet, False);
+  WriteLn;
+
+  WriteLn('High(type), s8 should be true, u64/s64 should cause range check at compile time');
+  CheckResult(' u8 -> ',  High(u8) in LargeSet, False);
+  CheckResult(' s8 -> ',  High(s8) in LargeSet, True);
+  CheckResult('u16 -> ', High(u16) in LargeSet, False);
+  CheckResult('s16 -> ', High(s16) in LargeSet, False);
+  CheckResult('u32 -> ', High(u32) in LargeSet, False);
+  CheckResult('s32 -> ', High(s32) in LargeSet, False);
+  try
+//    CheckResult('u64 -> ', High(u64) in LargeSet);
+    WriteLn('u64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+//    CheckResult('s64 -> ', High(s64) in LargeSet);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+
+  WriteLn('Low(type), all false, except s64 -> range check error at compile time');
+  CheckResult(' u8 -> ',  Low(u8) in LargeSet, False);
+  CheckResult(' s8 -> ',  Low(s8) in LargeSet, False);
+  CheckResult('u16 -> ', Low(u16) in LargeSet, False);
+  CheckResult('s16 -> ', Low(s16) in LargeSet, False);
+  CheckResult('u32 -> ', Low(u32) in LargeSet, False);
+  CheckResult('s32 -> ', Low(s32) in LargeSet, False);
+  CheckResult('u64 -> ', Low(u64) in LargeSet, False);
+  try
+//    CheckResult('s64 -> ', Low(s64) in LargeSet);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- Variable against constant set [0, 2, 8..20] ---' );
+  WriteLn;
+
+  u8  := 10;
+  s8  := 10;
+  u16 := 10;
+  s16 := 10;
+  u32 := 10;
+  s32 := 10;
+  u64 := 10;
+  s64 := 10;
+
+  WriteLn('10, should be true');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20], True);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20], True);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20], True);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20], True);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20], True);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20], True);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20], True);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20], True);
+  WriteLn;
+
+  u8  := 7;
+  s8  := 7;
+  u16 := 7;
+  s16 := 7;
+  u32 := 7;
+  s32 := 7;
+  u64 := 7;
+  s64 := 7;
+
+  WriteLn('7, should be false');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20], False);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20], False);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20], False);
+  WriteLn;
+
+  u8  := 30;
+  s8  := 30;
+  u16 := 30;
+  s16 := 30;
+  u32 := 30;
+  s32 := 30;
+  u64 := 30;
+  s64 := 30;
+
+  WriteLn('30, should be false');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20], False);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20], False);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20], False);
+  WriteLn;
+
+//  u8  := 256;
+//  s8  := 256;
+  u16 := 256;
+  s16 := 256;
+  u32 := 256;
+  s32 := 256;
+  u64 := 256;
+  s64 := 256;
+
+  WriteLn('256, should be false');
+//  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20], False);
+//  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20], False);
+  CheckResult('s64 -> ', s64 in [0, 2, 8..20], False);
+  WriteLn;
+
+  u8  := High(u8);
+  s8  := High(s8);
+  u16 := High(u16);
+  s16 := High(s16);
+  u32 := High(u32);
+  s32 := High(s32);
+  u64 := High(u64);
+  s64 := High(s64);
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check');
+  CheckResult(' u8 -> ',  u8 in [0, 2, 8..20], False);
+  CheckResult(' s8 -> ',  s8 in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20], False);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20], False);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20], False);
+  try
+    CheckResult('u64 -> ', u64 in [0, 2, 8..20]);
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+    CheckResult('s64 -> ', s64 in [0, 2, 8..20]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  u8  := Low(u8);
+  s8  := Low(s8);
+  u16 := Low(u16);
+  s16 := Low(s16);
+  u32 := Low(u32);
+  s32 := Low(s32);
+  u64 := Low(u64);
+  s64 := Low(s64);
+
+  WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error');
+  CheckResult('u8  -> ',  u8 in [0, 2, 8..20], True);
+  CheckResult('s8  -> ',  s8 in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', u16 in [0, 2, 8..20], True);
+  CheckResult('s16 -> ', s16 in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', u32 in [0, 2, 8..20], True);
+  CheckResult('s32 -> ', s32 in [0, 2, 8..20], False);
+  CheckResult('u64 -> ', u64 in [0, 2, 8..20], True);
+
+  try
+    CheckResult('s64 -> ', s64 in [0, 2, 8..20]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- Variable against set of 0..31 with value [0, 2, 8..20] ---' );
+  WriteLn;
+
+  SmallSet := [10..16];
+
+  u8  := 10;
+  s8  := 10;
+  u16 := 10;
+  s16 := 10;
+  u32 := 10;
+  s32 := 10;
+  u64 := 10;
+  s64 := 10;
+
+  WriteLn('10, should be true');
+  CheckResult(' u8 -> ',  u8 in SmallSet, True);
+  CheckResult(' s8 -> ',  s8 in SmallSet, True);
+  CheckResult('u16 -> ', u16 in SmallSet, True);
+  CheckResult('s16 -> ', s16 in SmallSet, True);
+  CheckResult('u32 -> ', u32 in SmallSet, True);
+  CheckResult('s32 -> ', s32 in SmallSet, True);
+  CheckResult('u64 -> ', u64 in SmallSet, True);
+  CheckResult('s64 -> ', s64 in SmallSet, True);
+  WriteLn;
+
+  u8  := 9;
+  s8  := 9;
+  u16 := 9;
+  s16 := 9;
+  u32 := 9;
+  s32 := 9;
+  u64 := 9;
+  s64 := 9;
+
+  WriteLn('9, should be false');
+  CheckResult(' u8 -> ',  u8 in SmallSet, False);
+  CheckResult(' s8 -> ',  s8 in SmallSet, False);
+  CheckResult('u16 -> ', u16 in SmallSet, False);
+  CheckResult('s16 -> ', s16 in SmallSet, False);
+  CheckResult('u32 -> ', u32 in SmallSet, False);
+  CheckResult('s32 -> ', s32 in SmallSet, False);
+  CheckResult('u64 -> ', u64 in SmallSet, False);
+  CheckResult('s64 -> ', s64 in SmallSet, False);
+  WriteLn;
+
+  u8  := 17;
+  s8  := 17;
+  u16 := 17;
+  s16 := 17;
+  u32 := 17;
+  s32 := 17;
+  u64 := 17;
+  s64 := 17;
+
+  WriteLn('17, should be false');
+  CheckResult(' u8 -> ',  u8 in SmallSet, False);
+  CheckResult(' s8 -> ',  s8 in SmallSet, False);
+  CheckResult('u16 -> ', u16 in SmallSet, False);
+  CheckResult('s16 -> ', s16 in SmallSet, False);
+  CheckResult('u32 -> ', u32 in SmallSet, False);
+  CheckResult('s32 -> ', s32 in SmallSet, False);
+  CheckResult('u64 -> ', u64 in SmallSet, False);
+  CheckResult('s64 -> ', s64 in SmallSet, False);
+  WriteLn;
+
+//  u8  := 256;
+//  s8  := 256;
+  u16 := 256;
+  s16 := 256;
+  u32 := 256;
+  s32 := 256;
+  u64 := 256;
+  s64 := 256;
+
+  WriteLn('256, should be false');
+//  CheckResult(' u8 -> ',  u8 in SmallSet, False);
+//  CheckResult(' s8 -> ',  s8 in SmallSet, False);
+  CheckResult('u16 -> ', u16 in SmallSet, False);
+  CheckResult('s16 -> ', s16 in SmallSet, False);
+  CheckResult('u32 -> ', u32 in SmallSet, False);
+  CheckResult('s32 -> ', s32 in SmallSet, False);
+  CheckResult('u64 -> ', u64 in SmallSet, False);
+  CheckResult('s64 -> ', s64 in SmallSet, False);
+  WriteLn;
+
+  u8  := High(u8);
+  s8  := High(s8);
+  u16 := High(u16);
+  s16 := High(s16);
+  u32 := High(u32);
+  s32 := High(s32);
+  u64 := High(u64);
+  s64 := High(s64);
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check');
+  CheckResult(' u8 -> ',  u8 in SmallSet, False);
+  CheckResult(' s8 -> ',  s8 in SmallSet, False);
+  CheckResult('u16 -> ', u16 in SmallSet, False);
+  CheckResult('s16 -> ', s16 in SmallSet, False);
+  CheckResult('u32 -> ', u32 in SmallSet, False);
+  CheckResult('s32 -> ', s32 in SmallSet, False);
+  try
+    CheckResult('u64 -> ', u64 in SmallSet);
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+    CheckResult('s64 -> ', s64 in SmallSet);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  u8  := Low(u8);
+  s8  := Low(s8);
+  u16 := Low(u16);
+  s16 := Low(s16);
+  u32 := Low(u32);
+  s32 := Low(s32);
+  u64 := Low(u64);
+  s64 := Low(s64);
+
+  WriteLn('Low(type), all false, except s64 -> range check error');
+  CheckResult('u8  -> ',  u8 in SmallSet, False);
+  CheckResult('s8  -> ',  s8 in SmallSet, False);
+  CheckResult('u16 -> ', u16 in SmallSet, False);
+  CheckResult('s16 -> ', s16 in SmallSet, False);
+  CheckResult('u32 -> ', u32 in SmallSet, False);
+  CheckResult('s32 -> ', s32 in SmallSet, False);
+  CheckResult('u64 -> ', u64 in SmallSet, False);
+
+  try
+    CheckResult('s64 -> ', s64 in SmallSet);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- constant value against constant set [0, 2, 8..20] ---' );
+  WriteLn;
+
+  WriteLn('10, should be true');
+  CheckResult('10 -> ', 10 in [0, 2, 8..20], True);
+  WriteLn;
+
+  WriteLn('7, should be false');
+  CheckResult(' 7 -> ', 7 in [0, 2, 8..20], False);
+  WriteLn;
+
+  WriteLn('30, should be false');
+  CheckResult('30 -> ', 30 in [0, 2, 8..20], False);
+  WriteLn;
+
+  WriteLn('256, should be false');
+  CheckResult('256 -> ', 256 in [0, 2, 8..20], False);
+  WriteLn;
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check at compile time');
+  CheckResult(' u8 -> ', High(u8)  in [0, 2, 8..20], False);
+  CheckResult(' s8 -> ', High(s8)  in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', High(u16) in [0, 2, 8..20], False);
+  CheckResult('s16 -> ', High(s16) in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', High(u32) in [0, 2, 8..20], False);
+  CheckResult('s32 -> ', High(s32) in [0, 2, 8..20], False);
+  try
+//    CheckResult('u64 -> ', High(u64) in [0, 2, 8..20]);
+    WriteLn('u64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+//    CheckResult('s64 -> ', High(s64) in [0, 2, 8..20]);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error at compile time');
+  CheckResult('u8  -> ',  Low(u8) in [0, 2, 8..20], True);
+  CheckResult('s8  -> ',  Low(s8) in [0, 2, 8..20], False);
+  CheckResult('u16 -> ', Low(u16) in [0, 2, 8..20], True);
+  CheckResult('s16 -> ', Low(s16) in [0, 2, 8..20], False);
+  CheckResult('u32 -> ', Low(u32) in [0, 2, 8..20], True);
+  CheckResult('s32 -> ', Low(s32) in [0, 2, 8..20], False);
+  CheckResult('u64 -> ', Low(u64) in [0, 2, 8..20], True);
+
+  try
+//    CheckResult('s64 -> ', Low(s64) in [0, 2, 8..20]);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- constant value against set of 0..31 with value [0, 2, 8..20] ---' );
+  WriteLn;
+
+  SmallSet := [9..17];
+
+  WriteLn('10, should be true');
+  CheckResult('10 -> ', 10 in SmallSet, True);
+  WriteLn;
+
+  WriteLn('7, should be false');
+  CheckResult(' 7 -> ',  7 in SmallSet, False);
+  WriteLn;
+
+  WriteLn('18, should be false');
+  CheckResult('18 -> ', 18 in SmallSet, False);
+  WriteLn;
+
+  WriteLn('256, should be false');
+  CheckResult('256 -> ', 256 in SmallSet, False);
+  WriteLn;
+
+  WriteLn('High(type), all false, u64/s64 should cause range check at compile time');
+  CheckResult(' u8 -> ',  High(u8) in SmallSet, False);
+  CheckResult(' s8 -> ',  High(s8) in SmallSet, False);
+  CheckResult('u16 -> ', High(u16) in SmallSet, False);
+  CheckResult('s16 -> ', High(s16) in SmallSet, False);
+  CheckResult('u32 -> ', High(u32) in SmallSet, False);
+  CheckResult('s32 -> ', High(s32) in SmallSet, False);
+  try
+//    CheckResult('u64 -> ', High(u64) in SmallSet);
+    WriteLn('u64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+//    CheckResult('s64 -> ', High(s64) in SmallSet);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+
+  WriteLn('Low(type), all false, except s64 -> range check error at compile time');
+  CheckResult(' u8 -> ',  Low(u8) in SmallSet, False);
+  CheckResult(' s8 -> ',  Low(s8) in SmallSet, False);
+  CheckResult('u16 -> ', Low(u16) in SmallSet, False);
+  CheckResult('s16 -> ', Low(s16) in SmallSet, False);
+  CheckResult('u32 -> ', Low(u32) in SmallSet, False);
+  CheckResult('s32 -> ', Low(s32) in SmallSet, False);
+  CheckResult('u64 -> ', Low(u64) in SmallSet, False);
+  try
+//    CheckResult('s64 -> ', Low(s64) in SmallSet);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- Variable against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41] ---' );
+  WriteLn;
+
+  u8  := 25;
+  s8  := 25;
+  u16 := 25;
+  s16 := 25;
+  u32 := 25;
+  s32 := 25;
+  u64 := 25;
+  s64 := 25;
+
+  WriteLn('25, should be true');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  WriteLn;
+
+  u8  := 26;
+  s8  := 26;
+  u16 := 26;
+  s16 := 26;
+  u32 := 26;
+  s32 := 26;
+  u64 := 26;
+  s64 := 26;
+
+  WriteLn('26, should be false');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  WriteLn;
+
+  u8  := 49;
+  s8  := 49;
+  u16 := 49;
+  s16 := 49;
+  u32 := 49;
+  s32 := 49;
+  u64 := 49;
+  s64 := 49;
+
+  WriteLn('49, should be false');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  WriteLn;
+
+//  u8  := 256;
+//  s8  := 256;
+  u16 := 256;
+  s16 := 256;
+  u32 := 256;
+  s32 := 256;
+  u64 := 256;
+  s64 := 256;
+
+  WriteLn('256, should be false');
+//  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+//  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  WriteLn;
+
+  u8  := High(u8);
+  s8  := High(s8);
+  u16 := High(u16);
+  s16 := High(s16);
+  u32 := High(u32);
+  s32 := High(s32);
+  u64 := High(u64);
+  s64 := High(s64);
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  try
+    CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]);
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+    CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  u8  := Low(u8);
+  s8  := Low(s8);
+  u16 := Low(u16);
+  s16 := Low(s16);
+  u32 := Low(u32);
+  s32 := Low(s32);
+  u64 := Low(u64);
+  s64 := Low(s64);
+
+  WriteLn('Low(type), all false, except s64 -> range check error');
+  CheckResult('u8  -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s8  -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+
+  try
+    CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- constant value against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41] ---' );
+  WriteLn;
+
+  WriteLn('25, should be true');
+  CheckResult('25 -> ', 25 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True);
+  WriteLn;
+
+  WriteLn('26, should be false');
+  CheckResult(' 26 -> ', 26 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  WriteLn;
+
+  WriteLn('49, should be false');
+  CheckResult('49 -> ', 49 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  WriteLn;
+
+  WriteLn('256, should be false');
+  CheckResult('256 -> ', 256 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  WriteLn;
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check at compile time');
+  CheckResult(' u8 -> ', High(u8)  in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult(' s8 -> ', High(s8)  in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', High(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', High(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', High(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', High(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  try
+//    CheckResult('u64 -> ', High(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+    WriteLn('u64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+//    CheckResult('s64 -> ', High(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('Low(type), all false, except s64 -> range check error at compile time');
+  CheckResult('u8  -> ',  Low(u8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s8  -> ',  Low(s8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u16 -> ', Low(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s16 -> ', Low(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u32 -> ', Low(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('s32 -> ', Low(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+  CheckResult('u64 -> ', Low(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+
+  try
+//    CheckResult('s64 -> ', Low(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- Variable against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29] ---' );
+  WriteLn;
+
+  u8  := 25;
+  s8  := 25;
+  u16 := 25;
+  s16 := 25;
+  u32 := 25;
+  s32 := 25;
+  u64 := 25;
+  s64 := 25;
+
+  WriteLn('25, should be true');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  WriteLn;
+
+  u8  := 26;
+  s8  := 26;
+  u16 := 26;
+  s16 := 26;
+  u32 := 26;
+  s32 := 26;
+  u64 := 26;
+  s64 := 26;
+
+  WriteLn('26, should be false');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  WriteLn;
+
+  u8  := 30;
+  s8  := 30;
+  u16 := 30;
+  s16 := 30;
+  u32 := 30;
+  s32 := 30;
+  u64 := 30;
+  s64 := 30;
+
+  WriteLn('30, should be false');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  WriteLn;
+
+//  u8  := 256;
+//  s8  := 256;
+  u16 := 256;
+  s16 := 256;
+  u32 := 256;
+  s32 := 256;
+  u64 := 256;
+  s64 := 256;
+
+  WriteLn('256, should be false');
+//  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+//  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  WriteLn;
+
+  u8  := High(u8);
+  s8  := High(s8);
+  u16 := High(u16);
+  s16 := High(s16);
+  u32 := High(u32);
+  s32 := High(s32);
+  u64 := High(u64);
+  s64 := High(s64);
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check');
+  CheckResult(' u8 -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult(' s8 -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  try
+    CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]);
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+    CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  u8  := Low(u8);
+  s8  := Low(s8);
+  u16 := Low(u16);
+  s16 := Low(s16);
+  u32 := Low(u32);
+  s32 := Low(s32);
+  u64 := Low(u64);
+  s64 := Low(s64);
+
+  WriteLn('Low(type), all false, except s64 -> range check error');
+  CheckResult('u8  -> ',  u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s8  -> ',  s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+
+  try
+    CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]);
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('--- constant value against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29] ---' );
+  WriteLn;
+
+  WriteLn('25, should be true');
+  CheckResult('25 -> ', 25 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True);
+  WriteLn;
+
+  WriteLn('26, should be false');
+  CheckResult(' 26 -> ', 26 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  WriteLn;
+
+  WriteLn('30, should be false');
+  CheckResult('30 -> ', 30 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  WriteLn;
+
+  WriteLn('256, should be false');
+  CheckResult('256 -> ', 256 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  WriteLn;
+
+  WriteLn('High(type), should be false, u64/s64 should cause range check at compile time');
+  CheckResult(' u8 -> ', High(u8)  in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult(' s8 -> ', High(s8)  in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', High(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', High(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', High(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', High(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  try
+//    CheckResult('u64 -> ', High(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+    WriteLn('u64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('u64 -> ', E.Classname,': ',E.Message);
+  end;
+  try
+//    CheckResult('s64 -> ', High(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  WriteLn('Low(type), all false, except s64 -> range check error at compile time');
+  CheckResult('u8  -> ',  Low(u8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s8  -> ',  Low(s8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u16 -> ', Low(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s16 -> ', Low(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u32 -> ', Low(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('s32 -> ', Low(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+  CheckResult('u64 -> ', Low(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+
+  try
+//    CheckResult('s64 -> ', Low(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False);
+    WriteLn('s64 -> Error: range check error while evaluating constants');
+  except
+    on E: Exception do
+      WriteLn('s64 -> ', E.Classname,': ',E.Message);
+  end;
+  WriteLn;
+
+  if Error then begin
+    WriteLn('* * * ERROR * * * ERROR * * * ERROR * * * ERROR * * * ERROR * * * ERROR * * *');
+    Halt(1);
+  end else
+    Halt(0);
+end.