Sfoglia il codice sorgente

*** empty log message ***

peter 21 anni fa
parent
commit
8012731ede
6 ha cambiato i file con 613 aggiunte e 1097 eliminazioni
  1. 185 681
      compiler/i386/n386add.pas
  2. 25 13
      compiler/ncgadd.pas
  3. 46 40
      compiler/nmat.pas
  4. 6 2
      compiler/x86/cgx86.pas
  5. 344 348
      compiler/x86/nx86add.pas
  6. 7 13
      compiler/x86_64/nx64mat.pas

+ 185 - 681
compiler/i386/n386add.pas

@@ -31,14 +31,13 @@ interface
 
 
     type
     type
        ti386addnode = class(tx86addnode)
        ti386addnode = class(tx86addnode)
-          procedure second_addboolean;override;
-          procedure second_addsmallset;override;
-          procedure second_addmmxset;override;
-          procedure second_mul;override;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
+          procedure second_addmmxset;override;
           procedure second_addmmx;override;
           procedure second_addmmx;override;
 {$endif SUPPORT_MMX}
 {$endif SUPPORT_MMX}
           procedure second_add64bit;override;
           procedure second_add64bit;override;
+          procedure second_cmp64bit;override;
+          procedure second_mul;override;
        end;
        end;
 
 
   implementation
   implementation
@@ -47,260 +46,16 @@ interface
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
       symconst,symdef,paramgr,
       symconst,symdef,paramgr,
-      aasmbase,aasmtai,aasmcpu,defutil,htypechk,
-      cgbase,pass_2,regvars,
+      aasmbase,aasmtai,aasmcpu,
+      cgbase,
       ncon,nset,
       ncon,nset,
-      cga,cgx86,ncgutil,cgobj,cg64f32;
-
-{*****************************************************************************
-                                AddBoolean
-*****************************************************************************}
-
-    procedure ti386addnode.second_addboolean;
-      var
-        op      : TAsmOp;
-        opsize  : TCGSize;
-        cmpop,
-        isjump  : boolean;
-        otl,ofl : tasmlabel;
-      begin
-        { calculate the operator which is more difficult }
-        firstcomplex(self);
-
-        cmpop:=false;
-        if (torddef(left.resulttype.def).typ=bool8bit) or
-           (torddef(right.resulttype.def).typ=bool8bit) then
-         opsize:=OS_8
-        else
-          if (torddef(left.resulttype.def).typ=bool16bit) or
-             (torddef(right.resulttype.def).typ=bool16bit) then
-           opsize:=OS_16
-        else
-           opsize:=OS_32;
-
-        if (cs_full_boolean_eval in aktlocalswitches) or
-           (nodetype in [unequaln,ltn,lten,gtn,gten,equaln,xorn]) then
-          begin
-            if left.nodetype in [ordconstn,realconstn] then
-             swapleftright;
-
-            isjump:=(left.expectloc=LOC_JUMP);
-            if isjump then
-              begin
-                 otl:=truelabel;
-                 objectlibrary.getlabel(truelabel);
-                 ofl:=falselabel;
-                 objectlibrary.getlabel(falselabel);
-              end;
-            secondpass(left);
-            if left.location.loc in [LOC_FLAGS,LOC_JUMP] then
-             location_force_reg(exprasmlist,left.location,opsize,false);
-            if isjump then
-             begin
-               truelabel:=otl;
-               falselabel:=ofl;
-             end
-            else if left.location.loc=LOC_JUMP then
-              internalerror(200310081);
-
-            isjump:=(right.expectloc=LOC_JUMP);
-            if isjump then
-              begin
-                 otl:=truelabel;
-                 objectlibrary.getlabel(truelabel);
-                 ofl:=falselabel;
-                 objectlibrary.getlabel(falselabel);
-              end;
-            secondpass(right);
-            if right.location.loc in [LOC_FLAGS,LOC_JUMP] then
-             location_force_reg(exprasmlist,right.location,opsize,false);
-            if isjump then
-             begin
-               truelabel:=otl;
-               falselabel:=ofl;
-             end
-            else if left.location.loc=LOC_JUMP then
-              internalerror(200310082);
-
-            { left must be a register }
-            left_must_be_reg(opsize,false);
-            { compare the }
-            case nodetype of
-              ltn,lten,gtn,gten,
-              equaln,unequaln :
-                begin
-                  op:=A_CMP;
-                  cmpop:=true;
-                end;
-              xorn :
-                op:=A_XOR;
-              orn :
-                op:=A_OR;
-              andn :
-                op:=A_AND;
-              else
-                internalerror(200203247);
-            end;
-            emit_op_right_left(op,TCGSize2Opsize[opsize]);
-            location_freetemp(exprasmlist,right.location);
-            location_release(exprasmlist,right.location);
-            if cmpop then
-             begin
-               location_freetemp(exprasmlist,left.location);
-               location_release(exprasmlist,left.location);
-             end;
-            set_result_location(cmpop,true);
-         end
-        else
-         begin
-           case nodetype of
-             andn,
-             orn :
-               begin
-                 location_reset(location,LOC_JUMP,OS_NO);
-                 case nodetype of
-                   andn :
-                     begin
-                        otl:=truelabel;
-                        objectlibrary.getlabel(truelabel);
-                        secondpass(left);
-                        maketojumpbool(exprasmlist,left,lr_load_regvars);
-                        cg.a_label(exprasmlist,truelabel);
-                        truelabel:=otl;
-                     end;
-                   orn :
-                     begin
-                        ofl:=falselabel;
-                        objectlibrary.getlabel(falselabel);
-                        secondpass(left);
-                        maketojumpbool(exprasmlist,left,lr_load_regvars);
-                        cg.a_label(exprasmlist,falselabel);
-                        falselabel:=ofl;
-                     end;
-                   else
-                     internalerror(2003042212);
-                 end;
-                 secondpass(right);
-                 maketojumpbool(exprasmlist,right,lr_load_regvars);
-               end;
-             else
-               internalerror(2003042213);
-           end;
-         end;
-      end;
-
-
-{*****************************************************************************
-                                AddSmallSet
-*****************************************************************************}
-
-    procedure ti386addnode.second_addsmallset;
-      var
-        opsize : TCGSize;
-        op     : TAsmOp;
-        cmpop,
-        pushedfpu,
-        extra_not,
-        noswap : boolean;
-      begin
-        pass_left_and_right(pushedfpu);
-
-        { when a setdef is passed, it has to be a smallset }
-        if ((left.resulttype.def.deftype=setdef) and
-            (tsetdef(left.resulttype.def).settype<>smallset)) or
-           ((right.resulttype.def.deftype=setdef) and
-            (tsetdef(right.resulttype.def).settype<>smallset)) then
-         internalerror(200203301);
-
-        cmpop:=false;
-        noswap:=false;
-        extra_not:=false;
-        opsize:=OS_32;
-        case nodetype of
-          addn :
-            begin
-              { this is a really ugly hack!!!!!!!!!! }
-              { this could be done later using EDI   }
-              { as it is done for subn               }
-              { instead of two registers!!!!         }
-              { adding elements is not commutative }
-              if (nf_swaped in flags) and (left.nodetype=setelementn) then
-               swapleftright;
-              { are we adding set elements ? }
-              if right.nodetype=setelementn then
-               begin
-                 { no range support for smallsets! }
-                 if assigned(tsetelementnode(right).right) then
-                  internalerror(43244);
-                 { bts requires both elements to be registers }
-                 location_force_reg(exprasmlist,left.location,opsize,false);
-                 location_force_reg(exprasmlist,right.location,opsize,true);
-                 op:=A_BTS;
-                 noswap:=true;
-               end
-              else
-               op:=A_OR;
-            end;
-          symdifn :
-            op:=A_XOR;
-          muln :
-            op:=A_AND;
-          subn :
-            begin
-              op:=A_AND;
-              if (not(nf_swaped in flags)) and
-                 (right.location.loc=LOC_CONSTANT) then
-                right.location.value := not(right.location.value)
-              else if (nf_swaped in flags) and
-                      (left.location.loc=LOC_CONSTANT) then
-                left.location.value := not(left.location.value)
-              else
-                extra_not:=true;
-            end;
-          equaln,
-          unequaln :
-            begin
-              op:=A_CMP;
-              cmpop:=true;
-            end;
-          lten,gten:
-            begin
-              if (not(nf_swaped in flags) and (nodetype = lten)) or
-                 ((nf_swaped in flags) and (nodetype = gten)) then
-                swapleftright;
-              location_force_reg(exprasmlist,left.location,opsize,true);
-              emit_op_right_left(A_AND,TCGSize2Opsize[opsize]);
-              op:=A_CMP;
-              cmpop:=true;
-              { warning: ugly hack, we need a JE so change the node to equaln }
-              nodetype:=equaln;
-            end;
-          xorn :
-            op:=A_XOR;
-          orn :
-            op:=A_OR;
-          andn :
-            op:=A_AND;
-          else
-            internalerror(2003042215);
-        end;
-        { left must be a register }
-        left_must_be_reg(opsize,noswap);
-        emit_generic_code(op,opsize,true,extra_not,false);
-        location_freetemp(exprasmlist,right.location);
-        location_release(exprasmlist,right.location);
-        if cmpop then
-         begin
-           location_freetemp(exprasmlist,left.location);
-           location_release(exprasmlist,left.location);
-         end;
-        set_result_location(cmpop,true);
-      end;
+      cga,ncgutil,cgobj,cg64f32;
 
 
 {*****************************************************************************
 {*****************************************************************************
                                    addmmxset
                                    addmmxset
 *****************************************************************************}
 *****************************************************************************}
 
 
+{$ifdef SUPPORT_MMX}
     procedure ti386addnode.second_addmmxset;
     procedure ti386addnode.second_addmmxset;
 
 
     var opsize : TCGSize;
     var opsize : TCGSize;
@@ -377,6 +132,7 @@ interface
          end;
          end;
         set_result_location(cmpop,true);
         set_result_location(cmpop,true);
       end;
       end;
+{$endif SUPPORT_MMX}
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -390,13 +146,148 @@ interface
         opsize     : TOpSize;
         opsize     : TOpSize;
         hregister,
         hregister,
         hregister2 : tregister;
         hregister2 : tregister;
-        href       : treference;
         hl4        : tasmlabel;
         hl4        : tasmlabel;
-        pushedfpu,
         mboverflow,
         mboverflow,
-        cmpop,
         unsigned:boolean;
         unsigned:boolean;
         r:Tregister;
         r:Tregister;
+      begin
+        firstcomplex(self);
+        pass_left_right;
+
+        op1:=A_NONE;
+        op2:=A_NONE;
+        mboverflow:=false;
+        opsize:=S_L;
+        unsigned:=((left.resulttype.def.deftype=orddef) and
+                   (torddef(left.resulttype.def).typ=u64bit)) or
+                  ((right.resulttype.def.deftype=orddef) and
+                   (torddef(right.resulttype.def).typ=u64bit));
+        case nodetype of
+          addn :
+            begin
+              op:=OP_ADD;
+              mboverflow:=true;
+            end;
+          subn :
+            begin
+              op:=OP_SUB;
+              op1:=A_SUB;
+              op2:=A_SBB;
+              mboverflow:=true;
+            end;
+          xorn:
+            op:=OP_XOR;
+          orn:
+            op:=OP_OR;
+          andn:
+            op:=OP_AND;
+          else
+            begin
+              { everything should be handled in pass_1 (JM) }
+              internalerror(200109051);
+            end;
+        end;
+
+        { left and right no register?  }
+        { then one must be demanded    }
+        if (left.location.loc<>LOC_REGISTER) then
+         begin
+           if (right.location.loc<>LOC_REGISTER) then
+            begin
+              hregister:=cg.getintregister(exprasmlist,OS_INT);
+              hregister2:=cg.getintregister(exprasmlist,OS_INT);
+              cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
+              location_reset(left.location,LOC_REGISTER,OS_64);
+              left.location.registerlow:=hregister;
+              left.location.registerhigh:=hregister2;
+            end
+           else
+            begin
+              location_swap(left.location,right.location);
+              toggleflag(nf_swaped);
+            end;
+         end;
+
+        { at this point, left.location.loc should be LOC_REGISTER }
+        if right.location.loc=LOC_REGISTER then
+         begin
+           { when swapped another result register }
+           if (nodetype=subn) and (nf_swaped in flags) then
+            begin
+              cg64.a_op64_reg_reg(exprasmlist,op,
+                left.location.register64,
+                right.location.register64);
+              location_swap(left.location,right.location);
+              toggleflag(nf_swaped);
+            end
+           else
+            begin
+              cg64.a_op64_reg_reg(exprasmlist,op,
+                right.location.register64,
+                left.location.register64);
+            end;
+           location_release(exprasmlist,right.location);
+         end
+        else
+         begin
+           { right.location<>LOC_REGISTER }
+           if (nodetype=subn) and (nf_swaped in flags) then
+            begin
+              r:=cg.getintregister(exprasmlist,OS_INT);
+              cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
+              emit_reg_reg(op1,opsize,left.location.registerlow,r);
+              emit_reg_reg(A_MOV,opsize,r,left.location.registerlow);
+              cg64.a_load64high_loc_reg(exprasmlist,right.location,r);
+              { the carry flag is still ok }
+              emit_reg_reg(op2,opsize,left.location.registerhigh,r);
+              emit_reg_reg(A_MOV,opsize,r,left.location.registerhigh);
+              cg.ungetregister(exprasmlist,r);
+              if right.location.loc<>LOC_CREGISTER then
+               begin
+                 location_freetemp(exprasmlist,right.location);
+                 location_release(exprasmlist,right.location);
+               end;
+            end
+           else
+            begin
+              cg64.a_op64_loc_reg(exprasmlist,op,right.location,
+                left.location.register64);
+              if (right.location.loc<>LOC_CREGISTER) then
+               begin
+                 location_freetemp(exprasmlist,right.location);
+                 location_release(exprasmlist,right.location);
+               end;
+            end;
+         end;
+
+        { only in case of overflow operations }
+        { produce overflow code }
+        { we must put it here directly, because sign of operation }
+        { is in unsigned VAR!!                              }
+        if mboverflow then
+         begin
+           if cs_check_overflow in aktlocalswitches  then
+            begin
+              objectlibrary.getlabel(hl4);
+              if unsigned then
+                cg.a_jmp_flags(exprasmlist,F_AE,hl4)
+              else
+                cg.a_jmp_flags(exprasmlist,F_NO,hl4);
+              cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+              cg.a_label(exprasmlist,hl4);
+            end;
+         end;
+
+        location_copy(location,left.location);
+      end;
+
+
+    procedure ti386addnode.second_cmp64bit;
+      var
+        hregister,
+        hregister2 : tregister;
+        href       : treference;
+        unsigned   : boolean;
 
 
       procedure firstjmp64bitcmp;
       procedure firstjmp64bitcmp;
 
 
@@ -468,49 +359,12 @@ interface
       begin
       begin
         firstcomplex(self);
         firstcomplex(self);
 
 
-        pass_left_and_right(pushedfpu);
+        pass_left_right;
 
 
-        op1:=A_NONE;
-        op2:=A_NONE;
-        mboverflow:=false;
-        cmpop:=false;
-        opsize:=S_L;
         unsigned:=((left.resulttype.def.deftype=orddef) and
         unsigned:=((left.resulttype.def.deftype=orddef) and
                    (torddef(left.resulttype.def).typ=u64bit)) or
                    (torddef(left.resulttype.def).typ=u64bit)) or
                   ((right.resulttype.def.deftype=orddef) and
                   ((right.resulttype.def.deftype=orddef) and
                    (torddef(right.resulttype.def).typ=u64bit));
                    (torddef(right.resulttype.def).typ=u64bit));
-        case nodetype of
-          addn :
-            begin
-              op:=OP_ADD;
-              mboverflow:=true;
-            end;
-          subn :
-            begin
-              op:=OP_SUB;
-              op1:=A_SUB;
-              op2:=A_SBB;
-              mboverflow:=true;
-            end;
-          ltn,lten,
-          gtn,gten,
-          equaln,unequaln:
-            begin
-              op:=OP_NONE;
-              cmpop:=true;
-            end;
-          xorn:
-            op:=OP_XOR;
-          orn:
-            op:=OP_OR;
-          andn:
-            op:=OP_AND;
-          else
-            begin
-              { everything should be handled in pass_1 (JM) }
-              internalerror(200109051);
-            end;
-        end;
 
 
         { left and right no register?  }
         { left and right no register?  }
         { then one must be demanded    }
         { then one must be demanded    }
@@ -519,7 +373,7 @@ interface
            if (right.location.loc<>LOC_REGISTER) then
            if (right.location.loc<>LOC_REGISTER) then
             begin
             begin
               { we can reuse a CREGISTER for comparison }
               { we can reuse a CREGISTER for comparison }
-              if not((left.location.loc=LOC_CREGISTER) and cmpop) then
+              if (left.location.loc<>LOC_CREGISTER) then
                begin
                begin
                  hregister:=cg.getintregister(exprasmlist,OS_INT);
                  hregister:=cg.getintregister(exprasmlist,OS_INT);
                  hregister2:=cg.getintregister(exprasmlist,OS_INT);
                  hregister2:=cg.getintregister(exprasmlist,OS_INT);
@@ -539,126 +393,55 @@ interface
         { at this point, left.location.loc should be LOC_REGISTER }
         { at this point, left.location.loc should be LOC_REGISTER }
         if right.location.loc=LOC_REGISTER then
         if right.location.loc=LOC_REGISTER then
          begin
          begin
-           { when swapped another result register }
-           if (nodetype=subn) and (nf_swaped in flags) then
-            begin
-              cg64.a_op64_reg_reg(exprasmlist,op,
-                left.location.register64,
-                right.location.register64);
-              location_swap(left.location,right.location);
-              toggleflag(nf_swaped);
-            end
-           else if cmpop then
-            begin
-              emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
-              firstjmp64bitcmp;
-              emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
-              secondjmp64bitcmp;
-            end
-           else
-            begin
-              cg64.a_op64_reg_reg(exprasmlist,op,
-                right.location.register64,
-                left.location.register64);
-            end;
+           emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
+           firstjmp64bitcmp;
+           emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
+           secondjmp64bitcmp;
            location_release(exprasmlist,right.location);
            location_release(exprasmlist,right.location);
          end
          end
         else
         else
          begin
          begin
-           { right.location<>LOC_REGISTER }
-           if (nodetype=subn) and (nf_swaped in flags) then
-            begin
-              r:=cg.getintregister(exprasmlist,OS_INT);
-              cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
-              emit_reg_reg(op1,opsize,left.location.registerlow,r);
-              emit_reg_reg(A_MOV,opsize,r,left.location.registerlow);
-              cg64.a_load64high_loc_reg(exprasmlist,right.location,r);
-              { the carry flag is still ok }
-              emit_reg_reg(op2,opsize,left.location.registerhigh,r);
-              emit_reg_reg(A_MOV,opsize,r,left.location.registerhigh);
-              cg.ungetregister(exprasmlist,r);
-              if right.location.loc<>LOC_CREGISTER then
+           case right.location.loc of
+             LOC_CREGISTER :
                begin
                begin
-                 location_freetemp(exprasmlist,right.location);
-                 location_release(exprasmlist,right.location);
+                 emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
+                 firstjmp64bitcmp;
+                 emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
+                 secondjmp64bitcmp;
                end;
                end;
-            end
-           else if cmpop then
-            begin
-              case right.location.loc of
-                LOC_CREGISTER :
-                  begin
-                    emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
-                    firstjmp64bitcmp;
-                    emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
-                    secondjmp64bitcmp;
-                  end;
-                LOC_CREFERENCE,
-                LOC_REFERENCE :
-                  begin
-                    href:=right.location.reference;
-                    inc(href.offset,4);
-                    emit_ref_reg(A_CMP,S_L,href,left.location.registerhigh);
-                    firstjmp64bitcmp;
-                    emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.registerlow);
-                    secondjmp64bitcmp;
-                    cg.a_jmp_always(exprasmlist,falselabel);
-                    location_freetemp(exprasmlist,right.location);
-                    location_release(exprasmlist,right.location);
-                  end;
-                LOC_CONSTANT :
-                  begin
-                    exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,hi(right.location.valueqword),left.location.registerhigh));
-                    firstjmp64bitcmp;
-                    exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,lo(right.location.valueqword),left.location.registerlow));
-                    secondjmp64bitcmp;
-                  end;
-                else
-                  internalerror(200203282);
-              end;
-            end
-
-           else
-            begin
-              cg64.a_op64_loc_reg(exprasmlist,op,right.location,
-                left.location.register64);
-              if (right.location.loc<>LOC_CREGISTER) then
+             LOC_CREFERENCE,
+             LOC_REFERENCE :
                begin
                begin
+                 href:=right.location.reference;
+                 inc(href.offset,4);
+                 emit_ref_reg(A_CMP,S_L,href,left.location.registerhigh);
+                 firstjmp64bitcmp;
+                 emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.registerlow);
+                 secondjmp64bitcmp;
+                 cg.a_jmp_always(exprasmlist,falselabel);
                  location_freetemp(exprasmlist,right.location);
                  location_freetemp(exprasmlist,right.location);
                  location_release(exprasmlist,right.location);
                  location_release(exprasmlist,right.location);
                end;
                end;
-            end;
+             LOC_CONSTANT :
+               begin
+                 exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,hi(right.location.valueqword),left.location.registerhigh));
+                 firstjmp64bitcmp;
+                 exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,lo(right.location.valueqword),left.location.registerlow));
+                 secondjmp64bitcmp;
+               end;
+             else
+               internalerror(200203282);
+           end;
          end;
          end;
 
 
-        if (left.location.loc<>LOC_CREGISTER) and cmpop then
+        if (left.location.loc<>LOC_CREGISTER) then
          begin
          begin
            location_freetemp(exprasmlist,left.location);
            location_freetemp(exprasmlist,left.location);
            location_release(exprasmlist,left.location);
            location_release(exprasmlist,left.location);
          end;
          end;
 
 
-        { only in case of overflow operations }
-        { produce overflow code }
-        { we must put it here directly, because sign of operation }
-        { is in unsigned VAR!!                              }
-        if mboverflow then
-         begin
-           if cs_check_overflow in aktlocalswitches  then
-            begin
-              objectlibrary.getlabel(hl4);
-              if unsigned then
-               cg.a_jmp_flags(exprasmlist,F_AE,hl4)
-              else
-               cg.a_jmp_flags(exprasmlist,F_NO,hl4);
-              cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
-              cg.a_label(exprasmlist,hl4);
-            end;
-         end;
-
         { we have LOC_JUMP as result }
         { we have LOC_JUMP as result }
-        if cmpop then
-         location_reset(location,LOC_JUMP,OS_NO)
-        else
-         location_copy(location,left.location);
+        location_reset(location,LOC_JUMP,OS_NO)
       end;
       end;
 
 
 
 
@@ -851,8 +634,9 @@ interface
       end;
       end;
 {$endif SUPPORT_MMX}
 {$endif SUPPORT_MMX}
 
 
+
 {*****************************************************************************
 {*****************************************************************************
-                                MUL
+                                x86 MUL
 *****************************************************************************}
 *****************************************************************************}
 
 
     procedure ti386addnode.second_mul;
     procedure ti386addnode.second_mul;
@@ -902,292 +686,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.94  2004-01-20 12:59:37  florian
+  Revision 1.95  2004-02-04 19:22:27  peter
+  *** empty log message ***
+
+  Revision 1.94  2004/01/20 12:59:37  florian
     * common addnode code for x86-64 and i386
     * common addnode code for x86-64 and i386
 
 
   Revision 1.93  2004/01/14 17:19:04  peter
   Revision 1.93  2004/01/14 17:19:04  peter
     * disable addmmxset
     * disable addmmxset
-
-  Revision 1.92  2003/12/25 01:07:09  florian
-    + $fputype directive support
-    + single data type operations with sse unit
-    * fixed more x86-64 stuff
-
-  Revision 1.91  2003/12/24 00:10:02  florian
-    - delete parameter in cg64 methods removed
-
-  Revision 1.90  2003/12/23 22:13:41  peter
-    * overlfow support in second_mul
-
-  Revision 1.89  2003/12/21 11:28:41  daniel
-    * Some work to allow mmx instructions to be used for 32 byte sets
-
-  Revision 1.88  2003/12/06 01:15:23  florian
-    * reverted Peter's alloctemp patch; hopefully properly
-
-  Revision 1.87  2003/12/03 23:13:20  peter
-    * delayed paraloc allocation, a_param_*() gets extra parameter
-      if it needs to allocate temp or real paralocation
-    * optimized/simplified int-real loading
-
-  Revision 1.86  2003/10/17 14:38:32  peter
-    * 64k registers supported
-    * fixed some memory leaks
-
-  Revision 1.85  2003/10/13 09:38:22  florian
-    * fixed forgotten commit
-
-  Revision 1.84  2003/10/13 01:58:03  florian
-    * some ideas for mm support implemented
-
-  Revision 1.83  2003/10/10 17:48:14  peter
-    * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
-    * tregisteralloctor renamed to trgobj
-    * removed rgobj from a lot of units
-    * moved location_* and reference_* to cgobj
-    * first things for mmx register allocation
-
-  Revision 1.82  2003/10/09 21:31:37  daniel
-    * Register allocator splitted, ans abstract now
-
-  Revision 1.81  2003/10/08 09:13:16  florian
-    * fixed full bool evalution and bool xor, if the left or right side have LOC_JUMP
-
-  Revision 1.80  2003/10/01 20:34:49  peter
-    * procinfo unit contains tprocinfo
-    * cginfo renamed to cgbase
-    * moved cgmessage to verbose
-    * fixed ppc and sparc compiles
-
-  Revision 1.79  2003/09/28 21:48:20  peter
-    * fix register leaks
-
-  Revision 1.78  2003/09/28 13:35:40  peter
-    * shortstr compare updated for different calling conventions
-
-  Revision 1.77  2003/09/10 08:31:48  marco
-   * Patch from Peter for paraloc
-
-  Revision 1.76  2003/09/03 15:55:01  peter
-    * NEWRA branch merged
-
-  Revision 1.75.2.2  2003/08/31 13:50:16  daniel
-    * Remove sorting and use pregenerated indexes
-    * Some work on making things compile
-
-  Revision 1.75.2.1  2003/08/29 17:29:00  peter
-    * next batch of updates
-
-  Revision 1.75  2003/08/03 20:38:00  daniel
-    * Made code generator reverse or/add/and/xor/imul instructions when
-      possible to reduce the slowdown of spills.
-
-  Revision 1.74  2003/08/03 20:19:43  daniel
-    - Removed cmpop from Ti386addnode.second_addstring
-
-  Revision 1.73  2003/07/06 15:31:21  daniel
-    * Fixed register allocator. *Lots* of fixes.
-
-  Revision 1.72  2003/06/17 16:51:30  peter
-    * cycle fixes
-
-  Revision 1.71  2003/06/07 18:57:04  jonas
-    + added freeintparaloc
-    * ppc get/freeintparaloc now check whether the parameter regs are
-      properly allocated/deallocated (and get an extra list para)
-    * ppc a_call_* now internalerrors if pi_do_call is not yet set
-    * fixed lot of missing pi_do_call's
-
-  Revision 1.70  2003/06/03 13:01:59  daniel
-    * Register allocator finished
-
-  Revision 1.69  2003/05/30 23:49:18  jonas
-    * a_load_loc_reg now has an extra size parameter for the destination
-      register (properly fixes what I worked around in revision 1.106 of
-      ncgutil.pas)
-
-  Revision 1.68  2003/05/26 19:38:28  peter
-    * generic fpc_shorstr_concat
-    + fpc_shortstr_append_shortstr optimization
-
-  Revision 1.67  2003/05/22 21:32:29  peter
-    * removed some unit dependencies
-
-  Revision 1.66  2003/04/26 09:12:55  peter
-    * add string returns in LOC_REFERENCE
-
-  Revision 1.65  2003/04/23 20:16:04  peter
-    + added currency support based on int64
-    + is_64bit for use in cg units instead of is_64bitint
-    * removed cgmessage from n386add, replace with internalerrors
-
-  Revision 1.64  2003/04/23 09:51:16  daniel
-    * Removed usage of edi in a lot of places when new register allocator used
-    + Added newra versions of g_concatcopy and secondadd_float
-
-  Revision 1.63  2003/04/22 23:50:23  peter
-    * firstpass uses expectloc
-    * checks if there are differences between the expectloc and
-      location.loc from secondpass in EXTDEBUG
-
-  Revision 1.62  2003/04/22 10:09:35  daniel
-    + Implemented the actual register allocator
-    + Scratch registers unavailable when new register allocator used
-    + maybe_save/maybe_restore unavailable when new register allocator used
-
-  Revision 1.61  2003/04/17 10:02:48  daniel
-    * Tweaked register allocate/deallocate positition to less interferences
-      are generated.
-
-  Revision 1.60  2003/03/28 19:16:57  peter
-    * generic constructor working for i386
-    * remove fixed self register
-    * esi added as address register for i386
-
-  Revision 1.59  2003/03/13 19:52:23  jonas
-    * and more new register allocator fixes (in the i386 code generator this
-      time). At least now the ppc cross compiler can compile the linux
-      system unit again, but I haven't tested it.
-
-  Revision 1.58  2003/03/08 20:36:41  daniel
-    + Added newra version of Ti386shlshrnode
-    + Added interference graph construction code
-
-  Revision 1.57  2003/03/08 13:59:17  daniel
-    * Work to handle new register notation in ag386nsm
-    + Added newra version of Ti386moddivnode
-
-  Revision 1.56  2003/03/08 10:53:48  daniel
-    * Created newra version of secondmul in n386add.pas
-
-  Revision 1.55  2003/02/19 22:00:15  daniel
-    * Code generator converted to new register notation
-    - Horribily outdated todo.txt removed
-
-  Revision 1.54  2003/01/13 18:37:44  daniel
-    * Work on register conversion
-
-  Revision 1.53  2003/01/08 18:43:57  daniel
-   * Tregister changed into a record
-
-  Revision 1.52  2002/11/25 17:43:26  peter
-    * splitted defbase in defutil,symutil,defcmp
-    * merged isconvertable and is_equal into compare_defs(_ext)
-    * made operator search faster by walking the list only once
-
-  Revision 1.51  2002/11/15 01:58:56  peter
-    * merged changes from 1.0.7 up to 04-11
-      - -V option for generating bug report tracing
-      - more tracing for option parsing
-      - errors for cdecl and high()
-      - win32 import stabs
-      - win32 records<=8 are returned in eax:edx (turned off by default)
-      - heaptrc update
-      - more info for temp management in .s file with EXTDEBUG
-
-  Revision 1.50  2002/10/20 13:11:27  jonas
-    * re-enabled optimized version of comparisons with the empty string that
-      I accidentally disabled in revision 1.26
-
-  Revision 1.49  2002/08/23 16:14:49  peter
-    * tempgen cleanup
-    * tt_noreuse temp type added that will be used in genentrycode
-
-  Revision 1.48  2002/08/14 18:41:48  jonas
-    - remove valuelow/valuehigh fields from tlocation, because they depend
-      on the endianess of the host operating system -> difficult to get
-      right. Use lo/hi(location.valueqword) instead (remember to use
-      valueqword and not value!!)
-
-  Revision 1.47  2002/08/11 14:32:29  peter
-    * renamed current_library to objectlibrary
-
-  Revision 1.46  2002/08/11 13:24:16  peter
-    * saving of asmsymbols in ppu supported
-    * asmsymbollist global is removed and moved into a new class
-      tasmlibrarydata that will hold the info of a .a file which
-      corresponds with a single module. Added librarydata to tmodule
-      to keep the library info stored for the module. In the future the
-      objectfiles will also be stored to the tasmlibrarydata class
-    * all getlabel/newasmsymbol and friends are moved to the new class
-
-  Revision 1.45  2002/07/26 11:17:52  jonas
-    * the optimization of converting a multiplication with a power of two to
-      a shl is moved from n386add/secondpass to nadd/resulttypepass
-
-  Revision 1.44  2002/07/20 11:58:00  florian
-    * types.pas renamed to defbase.pas because D6 contains a types
-      unit so this would conflicts if D6 programms are compiled
-    + Willamette/SSE2 instructions to assembler added
-
-  Revision 1.43  2002/07/11 14:41:32  florian
-    * start of the new generic parameter handling
-
-  Revision 1.42  2002/07/07 09:52:33  florian
-    * powerpc target fixed, very simple units can be compiled
-    * some basic stuff for better callparanode handling, far from being finished
-
-  Revision 1.41  2002/07/01 18:46:31  peter
-    * internal linker
-    * reorganized aasm layer
-
-  Revision 1.40  2002/07/01 16:23:55  peter
-    * cg64 patch
-    * basics for currency
-    * asnode updates for class and interface (not finished)
-
-  Revision 1.39  2002/05/18 13:34:22  peter
-    * readded missing revisions
-
-  Revision 1.38  2002/05/16 19:46:51  carl
-  + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
-  + try to fix temp allocation (still in ifdef)
-  + generic constructor calls
-  + start of tassembler / tmodulebase class cleanup
-
-  Revision 1.36  2002/05/13 19:54:37  peter
-    * removed n386ld and n386util units
-    * maybe_save/maybe_restore added instead of the old maybe_push
-
-  Revision 1.35  2002/05/12 16:53:17  peter
-    * moved entry and exitcode to ncgutil and cgobj
-    * foreach gets extra argument for passing local data to the
-      iterator function
-    * -CR checks also class typecasts at runtime by changing them
-      into as
-    * fixed compiler to cycle with the -CR option
-    * fixed stabs with elf writer, finally the global variables can
-      be watched
-    * removed a lot of routines from cga unit and replaced them by
-      calls to cgobj
-    * u32bit-s32bit updates for and,or,xor nodes. When one element is
-      u32bit then the other is typecasted also to u32bit without giving
-      a rangecheck warning/error.
-    * fixed pascal calling method with reversing also the high tree in
-      the parast, detected by tcalcst3 test
-
-  Revision 1.34  2002/04/25 20:16:40  peter
-    * moved more routines from cga/n386util
-
-  Revision 1.33  2002/04/05 15:09:13  jonas
-    * fixed web bug 1915
-
-  Revision 1.32  2002/04/04 19:06:10  peter
-    * removed unused units
-    * use tlocation.size in cg.a_*loc*() routines
-
-  Revision 1.31  2002/04/02 17:11:35  peter
-    * tlocation,treference update
-    * LOC_CONSTANT added for better constant handling
-    * secondadd splitted in multiple routines
-    * location_force_reg added for loading a location to a register
-      of a specified size
-    * secondassignment parses now first the right and then the left node
-      (this is compatible with Kylix). This saves a lot of push/pop especially
-      with string operations
-    * adapted some routines to use the new cg methods
-
-  Revision 1.29  2002/03/04 19:10:13  peter
-    * removed compiler warnings
-
 }
 }

+ 25 - 13
compiler/ncgadd.pas

@@ -49,12 +49,16 @@ interface
           procedure second_op64bit;
           procedure second_op64bit;
           procedure second_opordinal;
           procedure second_opordinal;
 
 
+          procedure second_addstring;virtual;
           procedure second_addfloat;virtual;abstract;
           procedure second_addfloat;virtual;abstract;
           procedure second_addboolean;virtual;
           procedure second_addboolean;virtual;
           procedure second_addsmallset;virtual;
           procedure second_addsmallset;virtual;
-        {$ifdef i386}
+{$ifdef i386}
+{$ifdef SUPPORT_MMX}
           procedure second_addmmxset;virtual;abstract;
           procedure second_addmmxset;virtual;abstract;
-        {$endif}
+          procedure second_addmmx;virtual;abstract;
+{$endif SUPPORT_MMX}
+{$endif}
           procedure second_add64bit;virtual;
           procedure second_add64bit;virtual;
           procedure second_addordinal;virtual;
           procedure second_addordinal;virtual;
           procedure second_cmpfloat;virtual;abstract;
           procedure second_cmpfloat;virtual;abstract;
@@ -70,14 +74,9 @@ interface
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
       symconst,symdef,paramgr,
       symconst,symdef,paramgr,
-      aasmbase,aasmtai,aasmcpu,defutil,htypechk,
-      cgbase,cpuinfo,pass_1,pass_2,regvars,
-      ncon,nset,ncgutil,tgobj,cgobj,
-{$ifdef cpu64bit}
-      cg64f64
-{$else cpu64bit}
-      cg64f32
-{$endif cpu64bit}
+      aasmbase,aasmtai,defutil,
+      cgbase,cpuinfo,pass_2,
+      ncon,nset,ncgutil,cgobj
       ;
       ;
 
 
 
 
@@ -557,6 +556,17 @@ interface
       end;
       end;
 
 
 
 
+{*****************************************************************************
+                                Strings
+*****************************************************************************}
+
+    procedure tcgaddnode.second_addstring;
+      begin
+        { this should already be handled in pass1 }
+        internalerror(2002072402);
+      end;
+
+
 {*****************************************************************************
 {*****************************************************************************
                                 Floats
                                 Floats
 *****************************************************************************}
 *****************************************************************************}
@@ -707,8 +717,7 @@ interface
             end;
             end;
           stringdef :
           stringdef :
             begin
             begin
-              { this should already be handled in pass1 }
-              internalerror(2002072402);
+              second_addstring;
             end;
             end;
           setdef :
           setdef :
             begin
             begin
@@ -749,7 +758,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.27  2004-01-31 17:45:17  peter
+  Revision 1.28  2004-02-04 19:22:27  peter
+  *** empty log message ***
+
+  Revision 1.27  2004/01/31 17:45:17  peter
     * Change several $ifdef i386 to x86
     * Change several $ifdef i386 to x86
     * Change several OS_32 to OS_INT/OS_ADDR
     * Change several OS_32 to OS_INT/OS_ADDR
 
 

+ 46 - 40
compiler/nmat.pas

@@ -34,9 +34,11 @@ interface
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
           function det_resulttype:tnode;override;
          protected
          protected
+{$ifndef cpu64bit}
           { override the following if you want to implement }
           { override the following if you want to implement }
           { parts explicitely in the code generator (JM)    }
           { parts explicitely in the code generator (JM)    }
           function first_moddiv64bitint: tnode; virtual;
           function first_moddiv64bitint: tnode; virtual;
+{$endif cpu64bit}
           function firstoptimize: tnode; virtual;
           function firstoptimize: tnode; virtual;
           function first_moddivint: tnode; virtual;
           function first_moddivint: tnode; virtual;
        end;
        end;
@@ -45,12 +47,14 @@ interface
        tshlshrnode = class(tbinopnode)
        tshlshrnode = class(tbinopnode)
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
           function det_resulttype:tnode;override;
+{$ifndef cpu64bit}
           { override the following if you want to implement }
           { override the following if you want to implement }
           { parts explicitely in the code generator (CEC)
           { parts explicitely in the code generator (CEC)
             Should return nil, if everything will be handled
             Should return nil, if everything will be handled
             in the code generator
             in the code generator
           }
           }
           function first_shlshr64bitint: tnode; virtual;
           function first_shlshr64bitint: tnode; virtual;
+{$endif cpu64bit}
        end;
        end;
        tshlshrnodeclass = class of tshlshrnode;
        tshlshrnodeclass = class of tshlshrnode;
 
 
@@ -66,8 +70,8 @@ interface
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
           function det_resulttype:tnode;override;
        {$ifdef state_tracking}
        {$ifdef state_tracking}
-    function track_state_pass(exec_known:boolean):boolean;override;
-  {$endif}
+          function track_state_pass(exec_known:boolean):boolean;override;
+       {$endif}
        end;
        end;
        tnotnodeclass = class of tnotnode;
        tnotnodeclass = class of tnotnode;
 
 
@@ -279,6 +283,7 @@ implementation
 {$endif cpuneedsdiv32helper}
 {$endif cpuneedsdiv32helper}
 
 
 
 
+{$ifndef cpu64bit}
     function tmoddivnode.first_moddiv64bitint: tnode;
     function tmoddivnode.first_moddiv64bitint: tnode;
       var
       var
         procname: string[31];
         procname: string[31];
@@ -311,6 +316,7 @@ implementation
         right := nil;
         right := nil;
         firstpass(result);
         firstpass(result);
       end;
       end;
+{$endif cpu64bit}
 
 
 
 
     function tmoddivnode.firstoptimize: tnode;
     function tmoddivnode.firstoptimize: tnode;
@@ -379,9 +385,11 @@ implementation
          if codegenerror then
          if codegenerror then
            exit;
            exit;
 
 
+         { Try to optimize mod/div }
          result := firstoptimize;
          result := firstoptimize;
          if assigned(result) then
          if assigned(result) then
            exit;
            exit;
+
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
          { 64bit }
          { 64bit }
          if (left.resulttype.def.deftype=orddef) and
          if (left.resulttype.def.deftype=orddef) and
@@ -413,32 +421,6 @@ implementation
                               TSHLSHRNODE
                               TSHLSHRNODE
  ****************************************************************************}
  ****************************************************************************}
 
 
-
-    function tshlshrnode.first_shlshr64bitint: tnode;
-      var
-        procname: string[31];
-      begin
-        result := nil;
-        { otherwise create a call to a helper }
-        if nodetype = shln then
-          procname := 'fpc_shl_int64'
-        else
-          procname := 'fpc_shr_int64';
-{        if is_signed(resulttype.def) then
-          procname := procname + 'int64'
-        else
-          procname := procname + 'qword';
-}
-        { this order of parameters works at least for the arm,
-          however it should work for any calling conventions (FK) }
-        result := ccallnode.createintern(procname,ccallparanode.create(right,
-          ccallparanode.create(left,nil)));
-        left := nil;
-        right := nil;
-        firstpass(result);
-      end;
-
-
     function tshlshrnode.det_resulttype:tnode;
     function tshlshrnode.det_resulttype:tnode;
       var
       var
          t : tnode;
          t : tnode;
@@ -474,12 +456,12 @@ implementation
 
 
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
          { 64 bit ints have their own shift handling }
          { 64 bit ints have their own shift handling }
-         if not(is_64bitint(left.resulttype.def)) then
+         if not is_64bit(left.resulttype.def) then
+{$endif cpu64bit}
            begin
            begin
              if torddef(left.resulttype.def).typ<>torddef(uinttype.def).typ then
              if torddef(left.resulttype.def).typ<>torddef(uinttype.def).typ then
                inserttypeconv(left,sinttype);
                inserttypeconv(left,sinttype);
            end;
            end;
-{$endif cpu64bit}
 
 
          inserttypeconv(right,sinttype);
          inserttypeconv(right,sinttype);
 
 
@@ -487,6 +469,28 @@ implementation
       end;
       end;
 
 
 
 
+{$ifndef cpu64bit}
+    function tshlshrnode.first_shlshr64bitint: tnode;
+      var
+        procname: string[31];
+      begin
+        result := nil;
+        { otherwise create a call to a helper }
+        if nodetype = shln then
+          procname := 'fpc_shl_int64'
+        else
+          procname := 'fpc_shr_int64';
+        { this order of parameters works at least for the arm,
+          however it should work for any calling conventions (FK) }
+        result := ccallnode.createintern(procname,ccallparanode.create(right,
+          ccallparanode.create(left,nil)));
+        left := nil;
+        right := nil;
+        firstpass(result);
+      end;
+{$endif cpu64bit}
+
+
     function tshlshrnode.pass_1 : tnode;
     function tshlshrnode.pass_1 : tnode;
       var
       var
          regs : longint;
          regs : longint;
@@ -504,7 +508,7 @@ implementation
              result := first_shlshr64bitint;
              result := first_shlshr64bitint;
              if assigned(result) then
              if assigned(result) then
                exit;
                exit;
-              regs:=2;
+             regs:=2;
            end
            end
          else
          else
 {$endif cpu64bit}
 {$endif cpu64bit}
@@ -513,7 +517,7 @@ implementation
            end;
            end;
 
 
          if (right.nodetype<>ordconstn) then
          if (right.nodetype<>ordconstn) then
-          inc(regs);
+           inc(regs);
          expectloc:=LOC_REGISTER;
          expectloc:=LOC_REGISTER;
          calcregisters(self,regs,0,0);
          calcregisters(self,regs,0,0);
       end;
       end;
@@ -844,15 +848,14 @@ implementation
 
 
 {$ifdef state_tracking}
 {$ifdef state_tracking}
     function Tnotnode.track_state_pass(exec_known:boolean):boolean;
     function Tnotnode.track_state_pass(exec_known:boolean):boolean;
-
-    begin
-  track_state_pass:=true;
-  if left.track_state_pass(exec_known) then
       begin
       begin
-    left.resulttype.def:=nil;
-    do_resulttypepass(left);
+        track_state_pass:=true;
+        if left.track_state_pass(exec_known) then
+          begin
+            left.resulttype.def:=nil;
+            do_resulttypepass(left);
+          end;
       end;
       end;
-    end;
 {$endif}
 {$endif}
 
 
 begin
 begin
@@ -863,7 +866,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.56  2004-02-03 22:32:54  peter
+  Revision 1.57  2004-02-04 19:22:27  peter
+  *** empty log message ***
+
+  Revision 1.56  2004/02/03 22:32:54  peter
     * renamed xNNbittype to xNNinttype
     * renamed xNNbittype to xNNinttype
     * renamed registers32 to registersint
     * renamed registers32 to registersint
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ

+ 6 - 2
compiler/x86/cgx86.pas

@@ -281,7 +281,8 @@ unit cgx86;
            OS_8,OS_S8 :
            OS_8,OS_S8 :
              if S1 in [OS_8,OS_S8] then
              if S1 in [OS_8,OS_S8] then
                s3 := S_B
                s3 := S_B
-             else internalerror(200109221);
+             else
+               internalerror(200109221);
            OS_16,OS_S16:
            OS_16,OS_S16:
              case s1 of
              case s1 of
                OS_8,OS_S8:
                OS_8,OS_S8:
@@ -1888,7 +1889,10 @@ unit cgx86;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.104  2004-02-03 19:46:48  jonas
+  Revision 1.105  2004-02-04 19:22:27  peter
+  *** empty log message ***
+
+  Revision 1.104  2004/02/03 19:46:48  jonas
     - removed "mov reg,reg" optimization (those instructions are removed by
     - removed "mov reg,reg" optimization (those instructions are removed by
       the register allocator, and may be necessary to indicate a register
       the register allocator, and may be necessary to indicate a register
       may not be released before some point)
       may not be released before some point)

+ 344 - 348
compiler/x86/nx86add.pas

@@ -36,19 +36,26 @@ unit nx86add;
 
 
     type
     type
       tx86addnode = class(tcgaddnode)
       tx86addnode = class(tcgaddnode)
+      protected
         function  getresflags(unsigned : boolean) : tresflags;
         function  getresflags(unsigned : boolean) : tresflags;
-        procedure set_result_location(cmpop,unsigned:boolean);
         procedure left_must_be_reg(opsize:TCGSize;noswap:boolean);
         procedure left_must_be_reg(opsize:TCGSize;noswap:boolean);
+        procedure left_and_right_must_be_fpureg;
         procedure emit_op_right_left(op:TAsmOp;opsize:TOpSize);
         procedure emit_op_right_left(op:TAsmOp;opsize:TOpSize);
         procedure emit_generic_code(op:TAsmOp;opsize:TCgSize;unsigned,extra_not,mboverflow:boolean);
         procedure emit_generic_code(op:TAsmOp;opsize:TCgSize;unsigned,extra_not,mboverflow:boolean);
 
 
-        function  first_addstring : tnode; override;
-        procedure pass_2;override;
-        procedure second_addfloat;override;
         procedure second_addfloatsse;
         procedure second_addfloatsse;
-        procedure second_addstring;
         procedure second_mul;virtual;abstract;
         procedure second_mul;virtual;abstract;
-        procedure pass_left_and_right(var pushedfpu:boolean);
+      public
+        function  first_addstring : tnode; override;
+        procedure second_addstring;override;
+        procedure second_addfloat;override;
+        procedure second_addsmallset;override;
+        procedure second_add64bit;override;
+        procedure second_addordinal;override;
+        procedure second_cmpfloat;override;
+        procedure second_cmpsmallset;override;
+        procedure second_cmp64bit;override;
+        procedure second_cmpordinal;override;
       end;
       end;
 
 
 
 
@@ -59,13 +66,12 @@ unit nx86add;
       verbose,
       verbose,
       cutils,
       cutils,
       aasmbase,aasmtai,aasmcpu,
       aasmbase,aasmtai,aasmcpu,
-      cpuinfo,
       symconst,symdef,
       symconst,symdef,
       cgobj,cgx86,cga,
       cgobj,cgx86,cga,
       paramgr,
       paramgr,
       htypechk,
       htypechk,
       pass_2,ncgutil,
       pass_2,ncgutil,
-      ncon,
+      ncon,nset,
       defutil;
       defutil;
 
 
 
 
@@ -186,6 +192,7 @@ unit nx86add;
          end;
          end;
       end;
       end;
 
 
+
     procedure tx86addnode.left_must_be_reg(opsize:TCGSize;noswap:boolean);
     procedure tx86addnode.left_must_be_reg(opsize:TCGSize;noswap:boolean);
       begin
       begin
         { left location is not a register? }
         { left location is not a register? }
@@ -209,6 +216,43 @@ unit nx86add;
        end;
        end;
 
 
 
 
+    procedure tx86addnode.left_and_right_must_be_fpureg;
+      begin
+        if (right.location.loc<>LOC_FPUREGISTER) then
+         begin
+           cg.a_loadfpu_loc_reg(exprasmlist,right.location,NR_ST);
+           if (right.location.loc <> LOC_CFPUREGISTER) then
+             location_freetemp(exprasmlist,left.location);
+           if (left.location.loc<>LOC_FPUREGISTER) then
+            begin
+              cg.a_loadfpu_loc_reg(exprasmlist,left.location,NR_ST);
+              if (left.location.loc <> LOC_CFPUREGISTER) then
+                location_freetemp(exprasmlist,left.location);
+            end
+           else
+            begin
+              { left was on the stack => swap }
+              toggleflag(nf_swaped);
+            end;
+
+           { releases the right reference }
+           location_release(exprasmlist,right.location);
+         end
+        { the nominator in st0 }
+        else if (left.location.loc<>LOC_FPUREGISTER) then
+         begin
+           cg.a_loadfpu_loc_reg(exprasmlist,left.location,NR_ST);
+           if (left.location.loc <> LOC_CFPUREGISTER) then
+             location_freetemp(exprasmlist,left.location);
+         end
+        else
+         begin
+           { fpu operands are always in the wrong order on the stack }
+           toggleflag(nf_swaped);
+         end;
+      end;
+
+
     procedure tx86addnode.emit_op_right_left(op:TAsmOp;opsize:TOpsize);
     procedure tx86addnode.emit_op_right_left(op:TAsmOp;opsize:TOpsize);
       begin
       begin
         { left must be a register }
         { left must be a register }
@@ -227,18 +271,6 @@ unit nx86add;
       end;
       end;
 
 
 
 
-    procedure tx86addnode.set_result_location(cmpop,unsigned:boolean);
-      begin
-        if cmpop then
-         begin
-           location_reset(location,LOC_FLAGS,OS_NO);
-           location.resflags:=getresflags(unsigned);
-         end
-        else
-         location_copy(location,left.location);
-      end;
-
-
     function tx86addnode.getresflags(unsigned : boolean) : tresflags;
     function tx86addnode.getresflags(unsigned : boolean) : tresflags;
       begin
       begin
          case nodetype of
          case nodetype of
@@ -284,168 +316,123 @@ unit nx86add;
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
-                                AddFloat
+                                AddSmallSet
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure tx86addnode.pass_left_and_right(var pushedfpu:boolean);
-      begin
-        { calculate the operator which is more difficult }
-        firstcomplex(self);
-
-        { in case of constant put it to the left }
-        if (left.nodetype=ordconstn) then
-         swapleftright;
-        secondpass(left);
-
-        { are too few registers free? }
-        if location.loc=LOC_FPUREGISTER then
-          pushedfpu:=maybe_pushfpu(exprasmlist,right.registersfpu,left.location)
-        else
-          pushedfpu:=false;
-        secondpass(right);
-      end;
-
-
-    procedure tx86addnode.second_addfloat;
+    procedure tx86addnode.second_addsmallset;
       var
       var
-        op         : TAsmOp;
-        resflags   : tresflags;
-        pushedfpu,
-        cmpop      : boolean;
+        opsize : TCGSize;
+        op     : TAsmOp;
+        extra_not,
+        noswap : boolean;
       begin
       begin
-        if use_sse(resulttype.def) then
-          begin
-            second_addfloatsse;
-            exit;
-          end;
-        pass_left_and_right(pushedfpu);
+        pass_left_right;
 
 
-        cmpop:=false;
+        noswap:=false;
+        extra_not:=false;
+        opsize:=OS_32;
         case nodetype of
         case nodetype of
           addn :
           addn :
-            op:=A_FADDP;
+            begin
+              { this is a really ugly hack!!!!!!!!!! }
+              { this could be done later using EDI   }
+              { as it is done for subn               }
+              { instead of two registers!!!!         }
+              { adding elements is not commutative }
+              if (nf_swaped in flags) and (left.nodetype=setelementn) then
+               swapleftright;
+              { are we adding set elements ? }
+              if right.nodetype=setelementn then
+               begin
+                 { no range support for smallsets! }
+                 if assigned(tsetelementnode(right).right) then
+                  internalerror(43244);
+                 { bts requires both elements to be registers }
+                 location_force_reg(exprasmlist,left.location,opsize,false);
+                 location_force_reg(exprasmlist,right.location,opsize,true);
+                 op:=A_BTS;
+                 noswap:=true;
+               end
+              else
+               op:=A_OR;
+            end;
+          symdifn :
+            op:=A_XOR;
           muln :
           muln :
-            op:=A_FMULP;
+            op:=A_AND;
           subn :
           subn :
-            op:=A_FSUBP;
-          slashn :
-            op:=A_FDIVP;
-          ltn,lten,gtn,gten,
-          equaln,unequaln :
             begin
             begin
-              op:=A_FCOMPP;
-              cmpop:=true;
+              op:=A_AND;
+              if (not(nf_swaped in flags)) and
+                 (right.location.loc=LOC_CONSTANT) then
+                right.location.value := not(right.location.value)
+              else if (nf_swaped in flags) and
+                      (left.location.loc=LOC_CONSTANT) then
+                left.location.value := not(left.location.value)
+              else
+                extra_not:=true;
             end;
             end;
+          xorn :
+            op:=A_XOR;
+          orn :
+            op:=A_OR;
+          andn :
+            op:=A_AND;
           else
           else
-            internalerror(2003042214);
+            internalerror(2003042215);
         end;
         end;
+        { left must be a register }
+        left_must_be_reg(opsize,noswap);
+        emit_generic_code(op,opsize,true,extra_not,false);
+        location_freetemp(exprasmlist,right.location);
+        location_release(exprasmlist,right.location);
 
 
-        if (right.location.loc<>LOC_FPUREGISTER) then
-         begin
-           cg.a_loadfpu_loc_reg(exprasmlist,right.location,NR_ST);
-           if (right.location.loc <> LOC_CFPUREGISTER) and
-              pushedfpu then
-             location_freetemp(exprasmlist,left.location);
-           if (left.location.loc<>LOC_FPUREGISTER) then
-            begin
-              cg.a_loadfpu_loc_reg(exprasmlist,left.location,NR_ST);
-              if (left.location.loc <> LOC_CFPUREGISTER) and
-                 pushedfpu then
-                location_freetemp(exprasmlist,left.location);
-            end
-           else
-            begin
-              { left was on the stack => swap }
-              toggleflag(nf_swaped);
-            end;
-
-           { releases the right reference }
-           location_release(exprasmlist,right.location);
-         end
-        { the nominator in st0 }
-        else if (left.location.loc<>LOC_FPUREGISTER) then
-         begin
-           cg.a_loadfpu_loc_reg(exprasmlist,left.location,NR_ST);
-           if (left.location.loc <> LOC_CFPUREGISTER) and
-              pushedfpu then
-             location_freetemp(exprasmlist,left.location);
-         end
-        else
-         begin
-           { fpu operands are always in the wrong order on the stack }
-           toggleflag(nf_swaped);
-         end;
-
-        { releases the left reference }
-        if (left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
-          location_release(exprasmlist,left.location);
+        set_result_location_reg;
+      end;
 
 
-        { if we swaped the tree nodes, then use the reverse operator }
-        if nf_swaped in flags then
-          begin
-             if (nodetype=slashn) then
-               op:=A_FDIVRP
-             else if (nodetype=subn) then
-               op:=A_FSUBRP;
-          end;
-        { to avoid the pentium bug
-        if (op=FDIVP) and (opt_processors=pentium) then
-          cg.a_call_name(exprasmlist,'EMUL_FDIVP')
-        else
-        }
-        { the Intel assemblers want operands }
-        if op<>A_FCOMPP then
-          begin
-             emit_reg_reg(op,S_NO,NR_ST,NR_ST1);
-             tcgx86(cg).dec_fpu_stack;
-          end
-        else
-          begin
-             emit_none(op,S_NO);
-             tcgx86(cg).dec_fpu_stack;
-             tcgx86(cg).dec_fpu_stack;
-          end;
 
 
-        { on comparison load flags }
-        if cmpop then
-         begin
-           cg.getexplicitregister(exprasmlist,NR_AX);
-           emit_reg(A_FNSTSW,S_NO,NR_AX);
-           emit_none(A_SAHF,S_NO);
-           cg.ungetregister(exprasmlist,NR_AX);
-           if nf_swaped in flags then
-            begin
-              case nodetype of
-                  equaln : resflags:=F_E;
-                unequaln : resflags:=F_NE;
-                     ltn : resflags:=F_A;
-                    lten : resflags:=F_AE;
-                     gtn : resflags:=F_B;
-                    gten : resflags:=F_BE;
-              end;
-            end
-           else
+    procedure tx86addnode.second_cmpsmallset;
+      var
+        opsize : TCGSize;
+        op     : TAsmOp;
+      begin
+        pass_left_right;
+        opsize:=OS_32;
+        case nodetype of
+          equaln,
+          unequaln :
+            op:=A_CMP;
+          lten,gten:
             begin
             begin
-              case nodetype of
-                  equaln : resflags:=F_E;
-                unequaln : resflags:=F_NE;
-                     ltn : resflags:=F_B;
-                    lten : resflags:=F_BE;
-                     gtn : resflags:=F_A;
-                    gten : resflags:=F_AE;
-              end;
+              if (not(nf_swaped in flags) and (nodetype = lten)) or
+                 ((nf_swaped in flags) and (nodetype = gten)) then
+                swapleftright;
+              location_force_reg(exprasmlist,left.location,opsize,true);
+              emit_op_right_left(A_AND,TCGSize2Opsize[opsize]);
+              op:=A_CMP;
+              { warning: ugly hack, we need a JE so change the node to equaln }
+              nodetype:=equaln;
             end;
             end;
-           location_reset(location,LOC_FLAGS,OS_NO);
-           location.resflags:=resflags;
-         end
-        else
-         begin
-           location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
-           location.register:=NR_ST;
-         end;
+          else
+            internalerror(2003042215);
+        end;
+        { left must be a register }
+        left_must_be_reg(opsize,false);
+        emit_generic_code(op,opsize,true,false,false);
+        location_freetemp(exprasmlist,right.location);
+        location_release(exprasmlist,right.location);
+        location_freetemp(exprasmlist,left.location);
+        location_release(exprasmlist,left.location);
+
+        location_reset(location,LOC_FLAGS,OS_NO);
+        location.resflags:=getresflags(true);
       end;
       end;
 
 
 
 
+{*****************************************************************************
+                                AddFloat
+*****************************************************************************}
+
     procedure tx86addnode.second_addfloatsse;
     procedure tx86addnode.second_addfloatsse;
       var
       var
         op : topcg;
         op : topcg;
@@ -498,6 +485,108 @@ unit nx86add;
           end;
           end;
       end;
       end;
 
 
+
+    procedure tx86addnode.second_addfloat;
+      var
+        op : TAsmOp;
+      begin
+        if use_sse(resulttype.def) then
+          begin
+            second_addfloatsse;
+            exit;
+          end;
+
+        pass_left_right;
+
+        case nodetype of
+          addn :
+            op:=A_FADDP;
+          muln :
+            op:=A_FMULP;
+          subn :
+            op:=A_FSUBP;
+          slashn :
+            op:=A_FDIVP;
+          else
+            internalerror(2003042214);
+        end;
+
+        left_and_right_must_be_fpureg;
+
+        { releases the left reference }
+        if (left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+          location_release(exprasmlist,left.location);
+
+        { if we swaped the tree nodes, then use the reverse operator }
+        if nf_swaped in flags then
+          begin
+             if (nodetype=slashn) then
+               op:=A_FDIVRP
+             else if (nodetype=subn) then
+               op:=A_FSUBRP;
+          end;
+
+        emit_reg_reg(op,S_NO,NR_ST,NR_ST1);
+        tcgx86(cg).dec_fpu_stack;
+
+        location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+        location.register:=NR_ST;
+      end;
+
+
+    procedure tx86addnode.second_cmpfloat;
+      var
+        resflags   : tresflags;
+      begin
+        if use_sse(resulttype.def) then
+          begin
+            second_addfloatsse;
+            exit;
+          end;
+
+        pass_left_right;
+        left_and_right_must_be_fpureg;
+
+        { releases the left reference }
+        if (left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+          location_release(exprasmlist,left.location);
+
+        emit_none(A_FCOMPP,S_NO);
+        tcgx86(cg).dec_fpu_stack;
+        tcgx86(cg).dec_fpu_stack;
+
+        { load fpu flags }
+        cg.getexplicitregister(exprasmlist,NR_AX);
+        emit_reg(A_FNSTSW,S_NO,NR_AX);
+        emit_none(A_SAHF,S_NO);
+        cg.ungetregister(exprasmlist,NR_AX);
+        if nf_swaped in flags then
+         begin
+           case nodetype of
+               equaln : resflags:=F_E;
+             unequaln : resflags:=F_NE;
+                  ltn : resflags:=F_A;
+                 lten : resflags:=F_AE;
+                  gtn : resflags:=F_B;
+                 gten : resflags:=F_BE;
+           end;
+         end
+        else
+         begin
+           case nodetype of
+               equaln : resflags:=F_E;
+             unequaln : resflags:=F_NE;
+                  ltn : resflags:=F_B;
+                 lten : resflags:=F_BE;
+                  gtn : resflags:=F_A;
+                 gten : resflags:=F_AE;
+           end;
+         end;
+        location_reset(location,LOC_FLAGS,OS_NO);
+        location.resflags:=resflags;
+      end;
+
+
 {*****************************************************************************
 {*****************************************************************************
                                 Addstring
                                 Addstring
 *****************************************************************************}
 *****************************************************************************}
@@ -507,7 +596,6 @@ unit nx86add;
     { ti386addnode.first_string and implement the shortstring concat    }
     { ti386addnode.first_string and implement the shortstring concat    }
     { manually! The generic routine is different from the i386 one (JM) }
     { manually! The generic routine is different from the i386 one (JM) }
     function tx86addnode.first_addstring : tnode;
     function tx86addnode.first_addstring : tnode;
-
       begin
       begin
         { special cases for shortstrings, handled in pass_2 (JM) }
         { special cases for shortstrings, handled in pass_2 (JM) }
         { can't handle fpc_shortstr_compare with compilerproc either because it }
         { can't handle fpc_shortstr_compare with compilerproc either because it }
@@ -592,7 +680,8 @@ unit nx86add;
                        location_freetemp(exprasmlist,right.location);
                        location_freetemp(exprasmlist,right.location);
                      end;
                      end;
                 end;
                 end;
-                set_result_location(true,true);
+                location_reset(location,LOC_FLAGS,OS_NO);
+                location.resflags:=getresflags(true);
              end;
              end;
            else
            else
              { rest should be handled in first pass (JM) }
              { rest should be handled in first pass (JM) }
@@ -600,218 +689,122 @@ unit nx86add;
        end;
        end;
      end;
      end;
 
 
+{*****************************************************************************
+                                  Add64bit
+*****************************************************************************}
+
+    procedure tx86addnode.second_add64bit;
+      begin
+{$ifdef cpu64bit}
+        second_addordinal;
+{$else cpu64bit}
+        { must be implemented separate }
+        internalerror(200402042);
+{$endif cpu64bit}
+      end;
+
+
+    procedure tx86addnode.second_cmp64bit;
+      begin
+{$ifdef cpu64bit}
+        second_cmpordinal;
+{$else cpu64bit}
+        { must be implemented separate }
+        internalerror(200402043);
+{$endif cpu64bit}
+      end;
+
 
 
 {*****************************************************************************
 {*****************************************************************************
-                                pass_2
+                                  AddOrdinal
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure tx86addnode.pass_2;
-    { is also being used for xor, and "mul", "sub, or and comparative }
-    { operators                                                }
+    procedure tx86addnode.second_addordinal;
       var
       var
-         pushedfpu,
-         mboverflow,cmpop : boolean;
+         mboverflow : boolean;
          op : tasmop;
          op : tasmop;
          opsize : tcgsize;
          opsize : tcgsize;
-
          { true, if unsigned types are compared }
          { true, if unsigned types are compared }
          unsigned : boolean;
          unsigned : boolean;
-         { is_in_dest if the result is put directly into }
-         { the resulting refernce or varregister }
-         {is_in_dest : boolean;}
          { true, if for sets subtractions the extra not should generated }
          { true, if for sets subtractions the extra not should generated }
          extra_not : boolean;
          extra_not : boolean;
-
       begin
       begin
-         { to make it more readable, string and set have their own procedures }
-         case left.resulttype.def.deftype of
-           orddef :
-             begin
-               { handling boolean expressions }
-               if is_boolean(left.resulttype.def) and
-                  is_boolean(right.resulttype.def) then
-                 begin
-                   second_addboolean;
-                   exit;
-                 end
-{$ifndef x86_64}
-               { 64bit operations }
-               else if is_64bit(left.resulttype.def) then
-                 begin
-                   second_add64bit;
-                   exit;
-                 end
-{$endif x86_64}
-               ;
-             end;
-           stringdef :
-             begin
-               second_addstring;
-               exit;
-             end;
-           setdef :
-             begin
-              {Normalsets are already handled in pass1 if mmx
-               should not be used.}
-              if (tsetdef(left.resulttype.def).settype<>smallset) then
-                begin
-{$ifdef MMXSET}
-                  if cs_mmx in aktlocalswitches then
-                    second_addmmxset
-                  else
-{$endif MMXSET}
-                    internalerror(200109041);
-                end
-              else
-                second_addsmallset;
-              exit;
-             end;
-           arraydef :
-             begin
-{$ifdef SUPPORT_MMX}
-               if is_mmx_able_array(left.resulttype.def) then
-                begin
-                  second_addmmx;
-                  exit;
-                end;
-{$endif SUPPORT_MMX}
-             end;
-           floatdef :
-             begin
-               second_addfloat;
-               exit;
-             end;
-         end;
-
          { defaults }
          { defaults }
-         {is_in_dest:=false;}
          extra_not:=false;
          extra_not:=false;
          mboverflow:=false;
          mboverflow:=false;
-         cmpop:=false;
          unsigned:=not(is_signed(left.resulttype.def)) or
          unsigned:=not(is_signed(left.resulttype.def)) or
                    not(is_signed(right.resulttype.def));
                    not(is_signed(right.resulttype.def));
          opsize:=def_cgsize(left.resulttype.def);
          opsize:=def_cgsize(left.resulttype.def);
 
 
-         pass_left_and_right(pushedfpu);
-
-         if (left.resulttype.def.deftype=pointerdef) or
-            (right.resulttype.def.deftype=pointerdef) or
-
-            (is_class_or_interface(right.resulttype.def) and is_class_or_interface(left.resulttype.def)) or
-
-            (left.resulttype.def.deftype=classrefdef) or
+         pass_left_right;
 
 
-            (left.resulttype.def.deftype=procvardef) or
-
-{$ifdef x86_64}
-            ((left.resulttype.def.deftype=enumdef) and
-             (left.resulttype.def.size in [4,8])) or
+         case nodetype of
+           addn :
+             begin
+               op:=A_ADD;
+               mboverflow:=true;
+             end;
+           muln :
+             begin
+               if unsigned then
+                 op:=A_MUL
+               else
+                 op:=A_IMUL;
+               mboverflow:=true;
+             end;
+           subn :
+             begin
+               op:=A_SUB;
+               mboverflow:=true;
+             end;
+           xorn :
+             op:=A_XOR;
+           orn :
+             op:=A_OR;
+           andn :
+             op:=A_AND;
+           else
+             internalerror(200304229);
+         end;
 
 
-            ((left.resulttype.def.deftype=orddef) and
-             (torddef(left.resulttype.def).typ in [s32bit,u32bit,s64bit,u64bit])) or
-            ((right.resulttype.def.deftype=orddef) and
-             (torddef(right.resulttype.def).typ in [s32bit,u32bit,s64bit,u64bit])) then
-{$else x86_64}
+         { filter MUL, which requires special handling }
+         if op=A_MUL then
+           begin
+             second_mul;
+             exit;
+           end;
 
 
-            ((left.resulttype.def.deftype=enumdef) and
-             (left.resulttype.def.size=4)) or
+         left_must_be_reg(opsize,false);
+         emit_generic_code(op,opsize,unsigned,extra_not,mboverflow);
+         location_freetemp(exprasmlist,right.location);
+         location_release(exprasmlist,right.location);
 
 
-            ((left.resulttype.def.deftype=orddef) and
-             (torddef(left.resulttype.def).typ in [s32bit,u32bit])) or
-            ((right.resulttype.def.deftype=orddef) and
-             (torddef(right.resulttype.def).typ in [s32bit,u32bit])) then
-{$endif x86_64}
-          begin
-            case nodetype of
-              addn :
-                begin
-                  op:=A_ADD;
-                  mboverflow:=true;
-                end;
-              muln :
-                begin
-                  if unsigned then
-                    op:=A_MUL
-                  else
-                    op:=A_IMUL;
-                  mboverflow:=true;
-                end;
-              subn :
-                begin
-                  op:=A_SUB;
-                  mboverflow:=true;
-                end;
-              ltn,lten,
-              gtn,gten,
-              equaln,unequaln :
-                begin
-                  op:=A_CMP;
-                  cmpop:=true;
-                end;
-              xorn :
-                op:=A_XOR;
-              orn :
-                op:=A_OR;
-              andn :
-                op:=A_AND;
-              else
-                internalerror(200304229);
-            end;
+         set_result_location_reg;
+      end;
 
 
-            { filter MUL, which requires special handling }
-            if op=A_MUL then
-             begin
-               second_mul;
-               exit;
-             end;
 
 
-            { Convert flags to register first }
-            if (left.location.loc=LOC_FLAGS) then
-             location_force_reg(exprasmlist,left.location,opsize,false);
-            if (right.location.loc=LOC_FLAGS) then
-             location_force_reg(exprasmlist,right.location,opsize,false);
+    procedure tx86addnode.second_cmpordinal;
+      var
+         opsize : tcgsize;
+         unsigned : boolean;
+      begin
+         unsigned:=not(is_signed(left.resulttype.def)) or
+                   not(is_signed(right.resulttype.def));
+         opsize:=def_cgsize(left.resulttype.def);
 
 
-            left_must_be_reg(opsize,false);
-            emit_generic_code(op,opsize,unsigned,extra_not,mboverflow);
-            location_freetemp(exprasmlist,right.location);
-            location_release(exprasmlist,right.location);
-            if cmpop and
-               (left.location.loc<>LOC_CREGISTER) then
-             begin
-               location_freetemp(exprasmlist,left.location);
-               location_release(exprasmlist,left.location);
-             end;
-            set_result_location(cmpop,unsigned);
-          end
+         pass_left_right;
 
 
-         { 8/16 bit enum,char,wchar types }
-         else
-          if ((left.resulttype.def.deftype=orddef) and
-              (torddef(left.resulttype.def).typ in [uchar,uwidechar])) or
-             ((left.resulttype.def.deftype=enumdef) and
-              ((left.resulttype.def.size=1) or
-               (left.resulttype.def.size=2))) then
+         left_must_be_reg(opsize,false);
+         emit_generic_code(A_CMP,opsize,unsigned,false,false);
+         location_freetemp(exprasmlist,right.location);
+         location_release(exprasmlist,right.location);
+         if (left.location.loc<>LOC_CREGISTER) then
            begin
            begin
-             case nodetype of
-               ltn,lten,gtn,gten,
-               equaln,unequaln :
-                 cmpop:=true;
-               else
-                 internalerror(2003042210);
-             end;
-             left_must_be_reg(opsize,false);
-             emit_op_right_left(A_CMP,TCGSize2Opsize[opsize]);
-             location_freetemp(exprasmlist,right.location);
-             location_release(exprasmlist,right.location);
-             if left.location.loc<>LOC_CREGISTER then
-              begin
-                location_freetemp(exprasmlist,left.location);
-                location_release(exprasmlist,left.location);
-              end;
-             set_result_location(true,true);
-           end
-         else
-           internalerror(2003042211);
+             location_freetemp(exprasmlist,left.location);
+             location_release(exprasmlist,left.location);
+           end;
+         location_reset(location,LOC_FLAGS,OS_NO);
+         location.resflags:=getresflags(unsigned);
       end;
       end;
 
 
 begin
 begin
@@ -819,7 +812,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.6  2004-01-20 12:59:37  florian
+  Revision 1.7  2004-02-04 19:22:27  peter
+  *** empty log message ***
+
+  Revision 1.6  2004/01/20 12:59:37  florian
     * common addnode code for x86-64 and i386
     * common addnode code for x86-64 and i386
 
 
   Revision 1.5  2003/12/26 13:19:16  florian
   Revision 1.5  2003/12/26 13:19:16  florian

+ 7 - 13
compiler/x86_64/nx64mat.pas

@@ -36,13 +36,12 @@ interface
 
 
       tx8664shlshrnode = class(tshlshrnode)
       tx8664shlshrnode = class(tshlshrnode)
          procedure pass_2;override;
          procedure pass_2;override;
-         { everything will be handled in pass_2 }
-         function first_shlshr64bitint: tnode; override;
       end;
       end;
 
 
       tx8664unaryminusnode = class(tx86unaryminusnode)
       tx8664unaryminusnode = class(tx86unaryminusnode)
       end;
       end;
 
 
+
 implementation
 implementation
 
 
     uses
     uses
@@ -62,7 +61,6 @@ implementation
       var
       var
         hreg1,hreg2:Tregister;
         hreg1,hreg2:Tregister;
         power:longint;
         power:longint;
-        hl:Tasmlabel;
         op:Tasmop;
         op:Tasmop;
       begin
       begin
         secondpass(left);
         secondpass(left);
@@ -161,16 +159,9 @@ implementation
 *****************************************************************************}
 *****************************************************************************}
 
 
 
 
-    function tx8664shlshrnode.first_shlshr64bitint: tnode;
-      begin
-        result:=nil;
-      end;
-
-
     procedure tx8664shlshrnode.pass_2;
     procedure tx8664shlshrnode.pass_2;
-      var hregisterhigh,hregisterlow:Tregister;
-          op:Tasmop;
-          l1,l2,l3:Tasmlabel;
+      var
+        op : Tasmop;
       begin
       begin
         secondpass(left);
         secondpass(left);
         secondpass(right);
         secondpass(right);
@@ -211,6 +202,9 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2004-01-20 12:59:37  florian
+  Revision 1.2  2004-02-04 19:22:27  peter
+  *** empty log message ***
+
+  Revision 1.1  2004/01/20 12:59:37  florian
     * common addnode code for x86-64 and i386
     * common addnode code for x86-64 and i386
 }
 }