Selaa lähdekoodia

+ intial implementation of add nodes, only integer/enumeration/pointer/...
handling is finished

Jonas Maebe 23 vuotta sitten
vanhempi
commit
0d740d4de8
2 muutettua tiedostoa jossa 1527 lisäystä ja 2 poistoa
  1. 6 2
      compiler/powerpc/cpunode.pas
  2. 1521 0
      compiler/powerpc/nppcadd.pas

+ 6 - 2
compiler/powerpc/cpunode.pas

@@ -35,7 +35,7 @@ unit cpunode;
          the processor specific nodes must be included
          after the generic one (FK)
        }
-//       nppcadd,
+       nppcadd,
 //       nppccal,
 //       nppccon,
 //       nppcflw,
@@ -52,7 +52,11 @@ unit cpunode;
 end.
 {
   $Log$
-  Revision 1.8  2002-07-21 16:58:59  jonas
+  Revision 1.9  2002-07-26 12:31:56  jonas
+    + intial implementation of add nodes, only integer/enumeration/pointer/...
+      handling is finished
+
+  Revision 1.8  2002/07/21 16:58:59  jonas
     + include ncgset unit
 
   Revision 1.7  2002/07/11 14:41:34  florian

+ 1521 - 0
compiler/powerpc/nppcadd.pas

@@ -0,0 +1,1521 @@
+{
+    $Id$
+    Copyright (c) 2000-2002 by Florian Klaempfl and Jonas Maebe
+
+    Code generation for add nodes on the PowerPC
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit nppcadd;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+       node,nadd,cpubase,cginfo;
+
+    type
+       tppcaddnode = class(taddnode)
+          procedure pass_2;override;
+         private
+          procedure pass_left_and_right(var pushedfpu:boolean);
+          function  getresflags : tresflags;
+{
+          procedure left_must_be_reg(opsize:TOpSize;noswap:boolean);
+          procedure emit_op_right_left(op:TAsmOp;opsize:TOpSize);
+          procedure emit_generic_code(op:TAsmOp;opsize:TOpSize;unsigned,extra_not,mboverflow:boolean);
+          procedure set_result_location(cmpop,unsigned:boolean);
+}
+          procedure second_addboolean; virtual; abstract;
+          procedure second_addfloat; virtual; abstract;
+          procedure second_addsmallset; virtual; abstract;
+{$ifdef SUPPORT_MMX}
+          procedure second_addmmx;
+{$endif SUPPORT_MMX}
+          procedure second_add64bit; virtual; abstract;
+       end;
+
+  implementation
+
+    uses
+      globtype,systems,
+      cutils,verbose,globals,
+      symconst,symdef,paramgr,
+      aasmbase,aasmtai,aasmcpu,defbase,htypechk,
+      cgbase,cpuinfo,pass_2,regvars,
+      cpupara,
+      ncon,nset,
+      cga,ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
+
+{*****************************************************************************
+                                  Helpers
+*****************************************************************************}
+
+    procedure tppcaddnode.pass_left_and_right(var pushedfpu:boolean);
+      var
+        pushedregs : tmaybesave;
+      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? }
+        maybe_save(exprasmlist,right.registers32,left.location,pushedregs);
+        if location.loc=LOC_FPUREGISTER then
+          pushedfpu:=maybe_pushfpu(exprasmlist,right.registersfpu,left.location)
+        else
+          pushedfpu:=false;
+        secondpass(right);
+        maybe_restore(exprasmlist,left.location,pushedregs);
+      end;
+
+
+    function tppcaddnode.getresflags : tresflags;
+      begin
+        if (left.resulttype.def.deftype <> floatdef) then
+          result.cr := R_CR0
+        else
+          result.cr := R_CR1;
+        case nodetype of
+          equaln : result.flag:=F_EQ;
+          unequaln : result.flag:=F_NE;
+        else
+          if nf_swaped in flags then
+            case nodetype of
+              ltn : result.flag:=F_GT;
+              lten : result.flag:=F_GE;
+              gtn : result.flag:=F_LT;
+              gten : result.flag:=F_LE;
+            end
+          else
+            case nodetype of
+              ltn : result.flag:=F_LT;
+              lten : result.flag:=F_LE;
+              gtn : result.flag:=F_GT;
+              gten : result.flag:=F_GE;
+            end;
+        end
+      end;
+
+(*
+    procedure tppcaddnode.left_must_be_reg(opsize:TOpSize;noswap:boolean);
+      begin
+        { left location is not a register? }
+        if (left.location.loc<>LOC_REGISTER) then
+         begin
+           { if right is register then we can swap the locations }
+           if (not noswap) and
+              (right.location.loc=LOC_REGISTER) then
+            begin
+              location_swap(left.location,right.location);
+              toggleflag(nf_swaped);
+            end
+           else
+            begin
+              { maybe we can reuse a constant register when the
+                operation is a comparison that doesn't change the
+                value of the register }
+              location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
+         end;
+       end;
+*)
+
+(*
+    procedure tppcaddnode.emit_op_right_left(op:TAsmOp;opsize:TOpsize);
+      begin
+        { left must be a register }
+        case right.location.loc of
+          LOC_REGISTER,
+          LOC_CREGISTER :
+            exprasmlist.concat(taicpu.op_reg_reg_reg(op,opsize,location.register,left.location.register,right.location.register));
+          LOC_CONSTANT :
+!!!            exprasmlist.concat(taicpu.op_const_reg(op,opsize,right.location.value,left.location.register));
+          else
+            internalerror(200203232);
+        end;
+      end;
+*)
+
+(*
+    procedure tppcaddnode.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;
+
+*)
+
+(*
+    procedure tppcaddnode.emit_generic_code(op:TAsmOp;opsize:TOpSize;unsigned,extra_not,mboverflow:boolean);
+      var
+        power : longint;
+        hl4   : tasmlabel;
+      begin
+        { at this point, left.location.loc should be LOC_REGISTER and right
+          should be a constant or in a register }
+        if (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+         begin
+           { right.location is a register }
+           { when swapped another result register }
+           if (nodetype=subn) and (nf_swaped in flags) then
+             op := A_SUBF;
+           { adapt for overflow checking if necessary }
+           if (cs_check_overflow in aktlocalswitches) then
+             case op of
+               A_ADD, A_SUB, A_SUBF:
+                 // convert to ADDO, SUBO, SUBFO
+                 op := succ(succ(op));
+             end;
+           exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register);
+         end
+        else
+         begin
+           { right.location is a constant }
+           if (right.location.loc <> LOC_CONSTANT) then
+             internalerror(2002072401);
+           if (nodetype=subn) and (nf_swaped in flags) then
+            begin
+              if extra_not then
+                emit_reg(A_NOT,opsize,left.location.register);
+              rg.getexplicitregisterint(exprasmlist,R_EDI);
+              cg.a_load_loc_reg(exprasmlist,right.location,R_EDI);
+              emit_reg_reg(op,opsize,left.location.register,R_EDI);
+              emit_reg_reg(A_MOV,opsize,R_EDI,left.location.register);
+              rg.ungetregisterint(exprasmlist,R_EDI);
+            end
+           else
+            begin
+               { Optimizations when right.location is a constant value }
+               if (op=A_CMP) and
+                  (nodetype in [equaln,unequaln]) and
+                  (right.location.loc=LOC_CONSTANT) and
+                  (right.location.value=0) then
+                 begin
+                   emit_reg_reg(A_TEST,opsize,left.location.register,left.location.register);
+                 end
+               else
+                 if (op=A_ADD) and
+                    (right.location.loc=LOC_CONSTANT) and
+                    (right.location.value=1) and
+                    not(cs_check_overflow in aktlocalswitches) then
+                  begin
+                    emit_reg(A_INC,opsize,left.location.register);
+                  end
+               else
+                 if (op=A_SUB) and
+                    (right.location.loc=LOC_CONSTANT) and
+                    (right.location.value=1) and
+                    not(cs_check_overflow in aktlocalswitches) then
+                  begin
+                    emit_reg(A_DEC,opsize,left.location.register);
+                  end
+               else
+                 if (op=A_IMUL) and
+                    (right.location.loc=LOC_CONSTANT) and
+                    (ispowerof2(right.location.value,power)) and
+                    not(cs_check_overflow in aktlocalswitches) then
+                  begin
+                    emit_const_reg(A_SHL,opsize,power,left.location.register);
+                  end
+               else
+                 begin
+                   if extra_not then
+                     begin
+                        rg.getexplicitregisterint(exprasmlist,R_EDI);
+                        cg.a_load_loc_reg(exprasmlist,right.location,R_EDI);
+                        emit_reg(A_NOT,S_L,R_EDI);
+                        emit_reg_reg(A_AND,S_L,R_EDI,left.location.register);
+                        rg.ungetregisterint(exprasmlist,R_EDI);
+                     end
+                   else
+                     begin
+                        emit_op_right_left(op,opsize);
+                     end;
+                 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
+              getlabel(hl4);
+              if unsigned then
+               emitjmp(C_NB,hl4)
+              else
+               emitjmp(C_NO,hl4);
+              cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+              cg.a_label(exprasmlist,hl4);
+            end;
+         end;
+      end;
+
+*)
+
+{*****************************************************************************
+                                AddBoolean
+*****************************************************************************}
+
+(*
+    procedure ti386addnode.second_addboolean;
+      var
+        op      : TAsmOp;
+        opsize  : TOpsize;
+        cmpop,
+        isjump  : boolean;
+        otl,ofl : tasmlabel;
+        pushedregs : tmaybesave;
+      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:=S_B
+        else
+          if (torddef(left.resulttype.def).typ=bool16bit) or
+             (torddef(right.resulttype.def).typ=bool16bit) then
+           opsize:=S_W
+        else
+           opsize:=S_L;
+
+        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.location.loc=LOC_JUMP);
+            if isjump then
+              begin
+                 otl:=truelabel;
+                 getlabel(truelabel);
+                 ofl:=falselabel;
+                 getlabel(falselabel);
+              end;
+            secondpass(left);
+            if left.location.loc in [LOC_FLAGS,LOC_JUMP] then
+             location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
+            if isjump then
+             begin
+               truelabel:=otl;
+               falselabel:=ofl;
+             end;
+
+            maybe_save(exprasmlist,right.registers32,left.location,pushedregs);
+            isjump:=(right.location.loc=LOC_JUMP);
+            if isjump then
+              begin
+                 otl:=truelabel;
+                 getlabel(truelabel);
+                 ofl:=falselabel;
+                 getlabel(falselabel);
+              end;
+            secondpass(right);
+            maybe_restore(exprasmlist,left.location,pushedregs);
+            if right.location.loc in [LOC_FLAGS,LOC_JUMP] then
+             location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],false);
+            if isjump then
+             begin
+               truelabel:=otl;
+               falselabel:=ofl;
+             end;
+
+            { 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,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;
+                        getlabel(truelabel);
+                        secondpass(left);
+                        maketojumpbool(exprasmlist,left,lr_load_regvars);
+                        cg.a_label(exprasmlist,truelabel);
+                        truelabel:=otl;
+                     end;
+                   orn :
+                     begin
+                        ofl:=falselabel;
+                        getlabel(falselabel);
+                        secondpass(left);
+                        maketojumpbool(exprasmlist,left,lr_load_regvars);
+                        cg.a_label(exprasmlist,falselabel);
+                        falselabel:=ofl;
+                     end;
+                   else
+                     CGMessage(type_e_mismatch);
+                 end;
+                 secondpass(right);
+                 maketojumpbool(exprasmlist,right,lr_load_regvars);
+               end;
+             else
+               CGMessage(type_e_mismatch);
+           end;
+         end;
+      end;
+*)
+
+{*****************************************************************************
+                                AddFloat
+*****************************************************************************}
+
+(*
+    procedure ti386addnode.second_addfloat;
+      var
+        op         : TAsmOp;
+        resflags   : tresflags;
+        pushedfpu,
+        cmpop      : boolean;
+      begin
+        pass_left_and_right(pushedfpu);
+
+        cmpop:=false;
+        case nodetype of
+          addn :
+            op:=A_FADDP;
+          muln :
+            op:=A_FMULP;
+          subn :
+            op:=A_FSUBP;
+          slashn :
+            op:=A_FDIVP;
+          ltn,lten,gtn,gten,
+          equaln,unequaln :
+            begin
+              op:=A_FCOMPP;
+              cmpop:=true;
+            end;
+          else
+            CGMessage(type_e_mismatch);
+        end;
+
+        if (right.location.loc<>LOC_FPUREGISTER) then
+         begin
+           cg.a_loadfpu_loc_reg(exprasmlist,
+               right.location,R_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,R_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,R_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);
+
+        { 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,R_ST,R_ST1);
+             dec(trgcpu(rg).fpuvaroffset);
+          end
+        else
+          begin
+             emit_none(op,S_NO);
+             dec(trgcpu(rg).fpuvaroffset,2);
+          end;
+
+        { on comparison load flags }
+        if cmpop then
+         begin
+           if not(R_EAX in rg.unusedregsint) then
+             begin
+               rg.getexplicitregisterint(exprasmlist,R_EDI);
+               emit_reg_reg(A_MOV,S_L,R_EAX,R_EDI);
+             end;
+           emit_reg(A_FNSTSW,S_NO,R_AX);
+           emit_none(A_SAHF,S_NO);
+           if not(R_EAX in rg.unusedregsint) then
+             begin
+               emit_reg_reg(A_MOV,S_L,R_EDI,R_EAX);
+               rg.ungetregisterint(exprasmlist,R_EDI);
+             end;
+           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
+        else
+         begin
+           location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+           location.register:=R_ST;
+         end;
+      end;
+*)
+
+{*****************************************************************************
+                                AddSmallSet
+*****************************************************************************}
+
+(*
+    procedure ti386addnode.second_addsmallset;
+      var
+        opsize : TOpSize;
+        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:=S_L;
+        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_2_cgsize[opsize],false);
+                 location_force_reg(exprasmlist,right.location,opsize_2_cgsize[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)) then
+                if (right.location.loc=LOC_CONSTANT) then
+                  right.location.value := not(right.location.value)
+                else
+                  op := A_ANDC
+              else
+                if (left.location.loc=LOC_CONSTANT) then
+                  left.location.value := not(left.location.value)
+                else
+                   begin
+                     swapleftright;
+                     op := A_ANDC;
+                   end;
+            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_2_cgsize[opsize],true);
+              emit_op_right_left(A_AND,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
+            begin
+              { no < or > support for sets }
+              CGMessage(type_e_mismatch);
+            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 cmpop then
+         begin
+           location_freetemp(exprasmlist,left.location);
+           location_release(exprasmlist,left.location);
+         end;
+        set_result_location(cmpop,true);
+      end;
+*)
+
+{*****************************************************************************
+                                Add64bit
+*****************************************************************************}
+
+(*
+    procedure ti386addnode.second_add64bit;
+      var
+        op         : TOpCG;
+        op1,op2    : TAsmOp;
+        opsize     : TOpSize;
+        hregister,
+        hregister2 : tregister;
+        href       : treference;
+        hl4        : tasmlabel;
+        pushedfpu,
+        mboverflow,
+        cmpop,
+        unsigned   : boolean;
+
+      procedure firstjmp64bitcmp;
+
+        var
+           oldnodetype : tnodetype;
+
+        begin
+           load_all_regvars(exprasmlist);
+           { the jump the sequence is a little bit hairy }
+           case nodetype of
+              ltn,gtn:
+                begin
+                   emitjmp(flags_to_cond(getresflags(unsigned)),truelabel);
+                   { cheat a little bit for the negative test }
+                   toggleflag(nf_swaped);
+                   emitjmp(flags_to_cond(getresflags(unsigned)),falselabel);
+                   toggleflag(nf_swaped);
+                end;
+              lten,gten:
+                begin
+                   oldnodetype:=nodetype;
+                   if nodetype=lten then
+                     nodetype:=ltn
+                   else
+                     nodetype:=gtn;
+                   emitjmp(flags_to_cond(getresflags(unsigned)),truelabel);
+                   { cheat for the negative test }
+                   if nodetype=ltn then
+                     nodetype:=gtn
+                   else
+                     nodetype:=ltn;
+                   emitjmp(flags_to_cond(getresflags(unsigned)),falselabel);
+                   nodetype:=oldnodetype;
+                end;
+              equaln:
+                emitjmp(C_NE,falselabel);
+              unequaln:
+                emitjmp(C_NE,truelabel);
+           end;
+        end;
+
+
+      procedure secondjmp64bitcmp;
+
+        begin
+           { the jump the sequence is a little bit hairy }
+           case nodetype of
+              ltn,gtn,lten,gten:
+                begin
+                   { the comparisaion of the low dword have to be }
+                   {  always unsigned!                            }
+                   emitjmp(flags_to_cond(getresflags(true)),truelabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
+                end;
+              equaln:
+                begin
+                   emitjmp(C_NE,falselabel);
+                   cg.a_jmp_always(exprasmlist,truelabel);
+                end;
+              unequaln:
+                begin
+                   emitjmp(C_NE,truelabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
+                end;
+           end;
+        end;
+
+      begin
+        firstcomplex(self);
+
+        pass_left_and_right(pushedfpu);
+
+        op1:=A_NONE;
+        op2:=A_NONE;
+        mboverflow:=false;
+        cmpop:=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;
+          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;
+          muln:
+            begin
+              { should be handled in pass_1 (JM) }
+              internalerror(200109051);
+            end;
+          else
+            CGMessage(type_e_mismatch);
+        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
+              { we can reuse a CREGISTER for comparison }
+              if not((left.location.loc=LOC_CREGISTER) and cmpop) then
+               begin
+                 if (left.location.loc<>LOC_CREGISTER) then
+                  begin
+                    location_freetemp(exprasmlist,left.location);
+                    location_release(exprasmlist,left.location);
+                  end;
+                 hregister:=rg.getregisterint(exprasmlist);
+                 hregister2:=rg.getregisterint(exprasmlist);
+                 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;
+            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 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;
+           location_release(exprasmlist,right.location);
+         end
+        else
+         begin
+           { right.location<>LOC_REGISTER }
+           if (nodetype=subn) and (nf_swaped in flags) then
+            begin
+              rg.getexplicitregisterint(exprasmlist,R_EDI);
+              cg64.a_load64low_loc_reg(exprasmlist,right.location,R_EDI);
+              emit_reg_reg(op1,opsize,left.location.registerlow,R_EDI);
+              emit_reg_reg(A_MOV,opsize,R_EDI,left.location.registerlow);
+              cg64.a_load64high_loc_reg(exprasmlist,right.location,R_EDI);
+              { the carry flag is still ok }
+              emit_reg_reg(op2,opsize,left.location.registerhigh,R_EDI);
+              emit_reg_reg(A_MOV,opsize,R_EDI,left.location.registerhigh);
+              rg.ungetregisterint(exprasmlist,R_EDI);
+              if right.location.loc<>LOC_CREGISTER then
+               begin
+                 location_freetemp(exprasmlist,right.location);
+                 location_release(exprasmlist,right.location);
+               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,right.location.valuehigh,left.location.registerhigh));
+                    firstjmp64bitcmp;
+                    exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,right.location.valuelow,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
+               begin
+                 location_freetemp(exprasmlist,right.location);
+                 location_release(exprasmlist,right.location);
+               end;
+            end;
+         end;
+
+        if (left.location.loc<>LOC_CREGISTER) and cmpop then
+         begin
+           location_freetemp(exprasmlist,left.location);
+           location_release(exprasmlist,left.location);
+         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
+              getlabel(hl4);
+              if unsigned then
+               emitjmp(C_NB,hl4)
+              else
+               emitjmp(C_NO,hl4);
+              cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
+              cg.a_label(exprasmlist,hl4);
+            end;
+         end;
+
+        { we have LOC_JUMP as result }
+        if cmpop then
+         location_reset(location,LOC_JUMP,OS_NO)
+        else
+         location_copy(location,left.location);
+      end;
+*)
+
+
+{*****************************************************************************
+                                AddMMX
+*****************************************************************************}
+
+{$ifdef SUPPORT_MMX}
+    procedure ti386addnode.second_addmmx;
+      var
+        op         : TAsmOp;
+        pushedfpu,
+        cmpop      : boolean;
+        mmxbase    : tmmxtype;
+        hregister  : tregister;
+      begin
+        pass_left_and_right(pushedfpu);
+
+        cmpop:=false;
+        mmxbase:=mmx_type(left.resulttype.def);
+        case nodetype of
+          addn :
+            begin
+              if (cs_mmx_saturation in aktlocalswitches) then
+                begin
+                   case mmxbase of
+                      mmxs8bit:
+                        op:=A_PADDSB;
+                      mmxu8bit:
+                        op:=A_PADDUSB;
+                      mmxs16bit,mmxfixed16:
+                        op:=A_PADDSB;
+                      mmxu16bit:
+                        op:=A_PADDUSW;
+                   end;
+                end
+              else
+                begin
+                   case mmxbase of
+                      mmxs8bit,mmxu8bit:
+                        op:=A_PADDB;
+                      mmxs16bit,mmxu16bit,mmxfixed16:
+                        op:=A_PADDW;
+                      mmxs32bit,mmxu32bit:
+                        op:=A_PADDD;
+                   end;
+                end;
+            end;
+          muln :
+            begin
+               case mmxbase of
+                  mmxs16bit,mmxu16bit:
+                    op:=A_PMULLW;
+                  mmxfixed16:
+                    op:=A_PMULHW;
+               end;
+            end;
+          subn :
+            begin
+              if (cs_mmx_saturation in aktlocalswitches) then
+                begin
+                   case mmxbase of
+                      mmxs8bit:
+                        op:=A_PSUBSB;
+                      mmxu8bit:
+                        op:=A_PSUBUSB;
+                      mmxs16bit,mmxfixed16:
+                        op:=A_PSUBSB;
+                      mmxu16bit:
+                        op:=A_PSUBUSW;
+                   end;
+                end
+              else
+                begin
+                   case mmxbase of
+                      mmxs8bit,mmxu8bit:
+                        op:=A_PSUBB;
+                      mmxs16bit,mmxu16bit,mmxfixed16:
+                        op:=A_PSUBW;
+                      mmxs32bit,mmxu32bit:
+                        op:=A_PSUBD;
+                   end;
+                end;
+            end;
+          xorn:
+            op:=A_PXOR;
+          orn:
+            op:=A_POR;
+          andn:
+            op:=A_PAND;
+          else
+            CGMessage(type_e_mismatch);
+        end;
+
+        { left and right no register?  }
+        { then one must be demanded    }
+        if (left.location.loc<>LOC_MMXREGISTER) then
+         begin
+           if (right.location.loc=LOC_MMXREGISTER) then
+            begin
+              location_swap(left.location,right.location);
+              toggleflag(nf_swaped);
+            end
+           else
+            begin
+              { register variable ? }
+              if (left.location.loc=LOC_CMMXREGISTER) then
+               begin
+                 hregister:=rg.getregistermm(exprasmlist);
+                 emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
+               end
+              else
+               begin
+                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                  internalerror(200203245);
+
+                 location_release(exprasmlist,left.location);
+
+                 hregister:=rg.getregistermm(exprasmlist);
+                 emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
+               end;
+
+              location_reset(left.location,LOC_MMXREGISTER,OS_NO);
+              left.location.register:=hregister;
+            end;
+         end;
+
+        { at this point, left.location.loc should be LOC_MMXREGISTER }
+        if right.location.loc<>LOC_MMXREGISTER then
+         begin
+           if (nodetype=subn) and (nf_swaped in flags) then
+            begin
+              if right.location.loc=LOC_CMMXREGISTER then
+               begin
+                 emit_reg_reg(A_MOVQ,S_NO,right.location.register,R_MM7);
+                 emit_reg_reg(op,S_NO,left.location.register,R_MM7);
+                 emit_reg_reg(A_MOVQ,S_NO,R_MM7,left.location.register);
+               end
+              else
+               begin
+                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                  internalerror(200203247);
+                 emit_ref_reg(A_MOVQ,S_NO,right.location.reference,R_MM7);
+                 emit_reg_reg(op,S_NO,left.location.register,R_MM7);
+                 emit_reg_reg(A_MOVQ,S_NO,R_MM7,left.location.register);
+                 location_release(exprasmlist,right.location);
+               end;
+            end
+           else
+            begin
+              if (right.location.loc=LOC_CMMXREGISTER) then
+               begin
+                 emit_reg_reg(op,S_NO,right.location.register,left.location.register);
+               end
+              else
+               begin
+                 if not(right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+                  internalerror(200203246);
+                 emit_ref_reg(op,S_NO,right.location.reference,left.location.register);
+                 location_release(exprasmlist,right.location);
+               end;
+            end;
+          end
+        else
+          begin
+            { right.location=LOC_MMXREGISTER }
+            if (nodetype=subn) and (nf_swaped in flags) then
+             begin
+               emit_reg_reg(op,S_NO,left.location.register,right.location.register);
+               location_swap(left.location,right.location);
+               toggleflag(nf_swaped);
+             end
+            else
+             begin
+               emit_reg_reg(op,S_NO,right.location.register,left.location.register);
+             end;
+          end;
+
+        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;
+{$endif SUPPORT_MMX}
+
+
+{*****************************************************************************
+                                pass_2
+*****************************************************************************}
+
+    procedure tppcaddnode.pass_2;
+    { is also being used for xor, and "mul", "sub, or and comparative }
+    { operators                                                }
+      var
+         pushedfpu,useconst,
+         { mboverflow, } cmpop : boolean;
+         op : tasmop;
+         cgop: topcg;
+{         cgsize : tcgsize; }
+         tmpreg: tregister;
+
+         { true, if unsigned types are compared }
+         unsigned : boolean;
+         { true, if for sets subtractions the extra not should generated }
+{         extra_not : boolean; }
+
+         regstopush: tregisterset;
+
+      begin
+         { to make it more readable, string and set (not smallset!) 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
+               { 64bit operations }
+               else if is_64bitint(left.resulttype.def) then
+                 begin
+                   second_add64bit;
+                   exit;
+                 end;
+             end;
+           stringdef :
+             begin
+               internalerror(2002072402);
+               exit;
+             end;
+           setdef :
+             begin
+               { normalsets are already handled in pass1 }
+               if (tsetdef(left.resulttype.def).settype<>smallset) then
+                internalerror(200109041);
+               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 }
+         {is_in_dest:=false;}
+{         extra_not:=false; }
+{         mboverflow:=false; }
+         cmpop:=nodetype in [ltn,lten,gtn,gten,equaln,unequaln];
+         unsigned:=not(is_signed(left.resulttype.def)) or
+                   not(is_signed(right.resulttype.def));
+{         cgsize := 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
+
+            (left.resulttype.def.deftype=procvardef) or
+
+            ((left.resulttype.def.deftype=enumdef) and
+             (left.resulttype.def.size=4)) or
+
+            ((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
+*)
+          begin
+            { Convert flags to register first }
+            { can any of these things be in the flags actually?? (JM) }
+
+            if (left.location.loc = LOC_FLAGS) or
+               (right.location.loc = LOC_FLAGS) then
+              internalerror(2002072602);
+{
+            if (left.location.loc=LOC_FLAGS) then
+             location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
+            if (right.location.loc=LOC_FLAGS) then
+             location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],false);
+}
+
+            { set result location }
+            if not cmpop then
+              location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def))
+             else
+              location_reset(location,LOC_FLAGS,OS_NO);
+
+            case left.location.loc of
+              LOC_REGISTER:
+                if not cmpop then
+                  location.register := left.location.register;
+              LOC_REFERENCE,LOC_CREFERENCE:
+                begin
+                  location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
+                  if not cmpop then
+                    location.register := left.location.register;
+                end;
+            end;
+            case right.location.loc of
+              LOC_REGISTER:
+                if not cmpop then
+                  location.register := right.location.register;
+              LOC_REFERENCE,LOC_CREFERENCE:
+                begin
+                  location_force_reg(exprasmlist,right.location,def_cgsize(right.resulttype.def),false);
+                  if not cmpop then
+                    location.register := right.location.register;
+                end;
+            end;
+
+            // when overflow checking is on, all operands have to be in
+            // a register
+            if (cs_check_overflow in aktlocalswitches) and
+               not cmpop and
+               not (nodetype in [orn,andn,xorn]) then
+              begin
+                { left and right can't be both constants }
+                if (left.location.loc = LOC_CONSTANT) then
+                  begin
+                    location_force_reg(exprasmlist,left.location,
+                      def_cgsize(left.resulttype.def),false);
+                     location.register := left.location.register;
+                   end
+                else if (right.location.loc = LOC_CONSTANT) then
+                  begin
+                    location_force_reg(exprasmlist,right.location,
+                      def_cgsize(right.resulttype.def),false);
+                    location.register := right.location.register;
+                  end;
+              end;
+
+            if (location.register = R_NO) and
+               not(cmpop) then
+              location.register := rg.getregisterint(exprasmlist);
+
+            if not(cs_check_overflow in aktlocalswitches) or
+               (cmpop) or
+               (nodetype in [orn,andn,xorn]) then
+              begin
+                case nodetype of
+                  addn, muln, xorn, orn, andn:
+                    begin
+                      case nodetype of
+                        addn:
+                          cgop := OP_ADD;
+                        muln:
+                          if unsigned then
+                            cgop := OP_MUL
+                          else 
+                            cgop := OP_IMUL;
+                        xorn:
+                          cgop := OP_XOR;
+                        orn:
+                          cgop := OP_OR;
+                        andn:
+                          cgop := OP_AND;
+                      end; 
+                      if (left.location.loc = LOC_CONSTANT) then
+                        swapleftright;
+                      if (right.location.loc <> LOC_CONSTANT) then
+                        cg.a_op_reg_reg_reg(exprasmlist,cgop,OS_INT,
+                          left.location.register,right.location.register,
+                          location.register)
+                      else
+                        cg.a_op_const_reg_reg(exprasmlist,cgop,OS_INT,
+                          aword(right.location.value),left.location.register,
+                        location.register);
+                    end;
+                  subn:
+                    begin
+                      if (nf_swaped in flags) then
+                        swapleftright;
+                      if left.location.loc <> LOC_CONSTANT then
+                        if right.location.loc <> LOC_CONSTANT then
+                          cg.a_op_reg_reg_reg(exprasmlist,OP_SUB,OS_INT,
+                            right.location.register,left.location.register,
+                            location.register)
+                        else
+                          cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
+                            aword(right.location.value),left.location.register,
+                            location.register)
+                      else
+                        if (longint(left.location.value) >= low(smallint)) and
+                           (longint(left.location.value) <= high(smallint)) then
+                          begin
+                            exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,
+                              location.register,right.location.register,
+                              left.location.value));
+                          end
+                        else
+                          begin
+                            tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                            cg.a_load_const_reg(exprasmlist,OS_INT,
+                              left.location.value,tmpreg);
+                            cg.a_op_reg_reg_reg(exprasmlist,OP_SUB,OS_INT,
+                              right.location.register,tmpreg,location.register);
+                            cg.free_scratch_reg(exprasmlist,tmpreg);
+                          end;
+                    end;
+                  ltn,lten,gtn,gten, equaln,unequaln :
+                    begin
+                      // get the constant on the right if there is one
+                      if (left.location.loc = LOC_CONSTANT) then
+                        swapleftright;
+                      // can we use an immediate, or do we have to load the
+                      // constant in a register first?
+                      if (right.location.loc = LOC_CONSTANT) then
+                        if (unsigned and
+                            (aword(right.location.value) > high(word))) or
+                           (not(unsigned) and
+                            ((longint(right.location.value) < low(smallint)) or
+                              (longint(right.location.value) > high(smallint)))) then
+                           useconst := true
+                        else
+                          begin
+                            useconst := false;
+                            tmpreg := cg.get_scratch_reg_int(exprasmlist);
+                            cg.a_load_const_reg(exprasmlist,OS_INT,
+                              aword(right.location.value),tmpreg);
+                           end
+                      else
+                        useconst := false;
+                      location.loc := LOC_FLAGS;
+                      location.resflags := getresflags;
+                      if not unsigned then
+                        if useconst then
+                          op := A_CMPWI
+                        else
+                          op := A_CMPW
+                      else
+                        if useconst then
+                          op := A_CMPLWI
+                        else
+                          op := A_CMPLW;
+
+                      if (right.location.loc = LOC_CONSTANT) then
+                        if useconst then
+                          exprasmlist.concat(taicpu.op_reg_const(op,
+                            left.location.register,right.location.value))
+                        else
+                          begin
+                            exprasmlist.concat(taicpu.op_reg_reg(op,
+                              left.location.register,tmpreg));
+                            cg.free_scratch_reg(exprasmlist,tmpreg);
+                          end
+                      else
+                        exprasmlist.concat(taicpu.op_reg_reg(op,
+                          left.location.register,right.location.register));
+                    end;
+                end
+              end
+            else
+              // overflow checking is on and we have an addn, subn or muln
+              begin
+                case nodetype of
+                  addn:
+                    op := A_ADDO;
+                  subn:
+                    op := A_SUBO;
+                  muln:
+                     op := A_MULLWO;
+                  else
+                    internalerror(2002072601);
+                end;
+                exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,
+                  left.location.register,right.location.register));
+              end;
+
+          end;
+
+          if (right.location.loc = LOC_REGISTER) and
+             (cmpop or
+              (location.register <> right.location.register)) then
+            rg.ungetregister(exprasmlist,right.location.register);
+          if (left.location.loc = LOC_REGISTER) and
+             (cmpop or
+              (location.register <> left.location.register)) then
+            rg.ungetregister(exprasmlist,left.location.register);
+
+            cg.g_overflowcheck(exprasmlist,self);
+(*
+         { 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
+           begin
+             case nodetype of
+               ltn,lten,gtn,gten,
+               equaln,unequaln :
+                 cmpop:=true;
+               else
+                 CGMessage(type_e_mismatch);
+             end;
+             left_must_be_reg(opsize,false);
+             emit_op_right_left(A_CMP,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
+           CGMessage(type_e_mismatch);
+*)
+      end;
+
+begin
+   caddnode:=tppcaddnode;
+end.
+{
+  $Log$
+  Revision 1.1  2002-07-26 12:31:57  jonas
+    + intial implementation of add nodes, only integer/enumeration/pointer/...
+      handling is finished
+
+
+}