Quellcode durchsuchen

* MIPS addnode: rewritten almost completely:
* shorter by 280 lines
* generates actual instructions instead of macros
* uses immediate operands for constants when possible
* 64-bit and float comparisons use LOC_JUMP as location

git-svn-id: trunk@24236 -

sergei vor 12 Jahren
Ursprung
Commit
02a288fd89
1 geänderte Dateien mit 202 neuen und 486 gelöschten Zeilen
  1. 202 486
      compiler/mips/ncpuadd.pas

+ 202 - 486
compiler/mips/ncpuadd.pas

@@ -34,23 +34,18 @@ type
 
   tmipsaddnode = class(tcgaddnode)
   private
-    function cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
-    function cmp64_le(left_reg, right_reg: TRegister64): TRegister;
-    function cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
-    function cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
-    function cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
-    function cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
-
-    function GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister;
-    function GetRes64_register(unsigned: boolean; {this_reg,} left_reg, right_reg: TRegister64): TRegister;
+    procedure cmp64_lt(left_reg, right_reg: TRegister64;unsigned:boolean);
+    procedure cmp64_le(left_reg, right_reg: TRegister64;unsigned:boolean);
+    procedure second_generic_cmp32(unsigned: boolean);
   protected
-    function pass_1: tnode; override;
     procedure second_addfloat; override;
     procedure second_cmpfloat; override;
     procedure second_cmpboolean; override;
     procedure second_cmpsmallset; override;
     procedure second_cmp64bit; override;
     procedure second_cmpordinal; override;
+  public
+    function pass_1: tnode; override;
   end;
 
 implementation
@@ -63,370 +58,219 @@ uses
   defutil,
   {cgbase,} cgcpu, cgutils,
   cpupara,
+  procinfo,
+  symconst,symdef,
   ncon, nset, nadd,
   ncgutil, cgobj;
 
 {*****************************************************************************
                                tmipsaddnode
 *****************************************************************************}
-function tmipsaddnode.GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister;
-var
-  tmp_asm_op: tasmop;
-begin
-  case NodeType of
-    equaln:
-      tmp_asm_op := A_SEQ;
-    unequaln:
-      tmp_asm_op := A_SNE;
-    else
-      if not (unsigned) then
-      begin
-        if nf_swapped in flags then
-          case NodeType of
-            ltn:
-              tmp_asm_op := A_SGT;
-            lten:
-              tmp_asm_op := A_SGE;
-            gtn:
-              tmp_asm_op := A_SLT;
-            gten:
-              tmp_asm_op := A_SLE;
-          end
-        else
-          case NodeType of
-            ltn:
-              tmp_asm_op := A_SLT;
-            lten:
-              tmp_asm_op := A_SLE;
-            gtn:
-              tmp_asm_op := A_SGT;
-            gten:
-              tmp_asm_op := A_SGE;
-          end;
-      end
-      else
-      begin
-        if nf_swapped in Flags then
-          case NodeType of
-            ltn:
-              tmp_asm_op := A_SGTU;
-            lten:
-              tmp_asm_op := A_SGEU;
-            gtn:
-              tmp_asm_op := A_SLTU;
-            gten:
-              tmp_asm_op := A_SLEU;
-          end
-        else
-          case NodeType of
-            ltn:
-              tmp_asm_op := A_SLTU;
-            lten:
-              tmp_asm_op := A_SLEU;
-            gtn:
-              tmp_asm_op := A_SGTU;
-            gten:
-              tmp_asm_op := A_SGEU;
-          end;
-      end;
-  end;
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(tmp_asm_op, this_reg, left_reg, right_reg));
-  GetRes_register := this_reg;
-end;
-
-function tmipsaddnode.cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
-var
-  lfcmp64_L4: tasmlabel;
-  tmpreg : TRegister;
-  ai : TaiCpu;
-begin
+const
+  swapped_nodetype: array[ltn..gten] of tnodetype =
+    //lt  lte  gt  gte
+    (gtn, gten,ltn,lten);
 
-  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  current_asmdata.getjumplabel(lfcmp64_L4);
+  ops: array[boolean] of tasmop = (A_SLT,A_SLTU);
+  ops_immed: array[boolean] of tasmop = (A_SLTI,A_SLTIU);
 
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0));
-
-  ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-
-  //current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reglo, right_reg.reglo, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 1));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_eq := tmpreg;
-end;
-
-function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
+procedure tmipsaddnode.second_generic_cmp32(unsigned: boolean);
 var
-  lfcmp64_L4: tasmlabel;
-  tmpreg : TRegister;
-  ai : TaiCpu;
+  ntype: tnodetype;
+  tmp_left,tmp_right: TRegister;
 begin
+  pass_left_right;
+  force_reg_left_right(True, True);
+  location_reset(location,LOC_REGISTER,OS_INT);
+  location.register:=cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
 
-  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  current_asmdata.getjumplabel(lfcmp64_L4);
-
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 1));
-
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-
-  //current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reglo, right_reg.reglo, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
+  if nodetype in [equaln,unequaln] then
+    begin
+      tmp_left:=location.register;
+      { XORI needs unsigned immediate in range 0-65535 }
+      if (right.location.loc=LOC_CONSTANT) and (right.location.value>=0) and
+        (right.location.value<=65535) then
+        begin
+          if right.location.value<>0 then
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_XORI,location.register,left.location.register,right.location.value))
+          else
+            tmp_left:=left.location.register;
+        end
+      else
+        begin
+          if (right.location.loc<>LOC_CONSTANT) then
+            tmp_right:=right.location.register
+          else
+            begin
+              tmp_right:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
+              cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,right.location.value,tmp_right);
+            end;
+          current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_XOR,location.register,left.location.register,tmp_right));
+        end;
+
+      if nodetype=equaln then
+        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,tmp_left,1))
+      else
+        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU,location.register,NR_R0,tmp_left));
+      exit;
+    end;
 
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0));
+  ntype:=nodetype;
+  if nf_swapped in flags then
+    ntype:=swapped_nodetype[nodetype];
+
+  {
+    sle  x,a,b  -->  slt   x,b,a; xori  x,x,1    immediate not possible (or must be at left)
+    sgt  x,a,b  -->  slt   x,b,a                 likewise
+    sge  x,a,b  -->  slt   x,a,b; xori  x,x,1
+    slt  x,a,b  -->  unchanged
+  }
+
+  if (ntype in [gten,ltn]) and
+    (right.location.loc=LOC_CONSTANT) and
+    (right.location.value>=simm16lo) and
+    (right.location.value<=simm16hi) then
+    current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(ops_immed[unsigned],location.register,left.location.register,right.location.value))
+  else
+    begin
+      if (right.location.loc=LOC_CONSTANT) then
+        begin
+          if (right.location.value=0) then
+            tmp_right:=NR_R0
+          else
+            begin
+             tmp_right:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
+             cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,right.location.value,tmp_right);
+          end;
+        end
+      else
+        tmp_right:=right.location.register;
 
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_ne := tmpreg;
+      if (ntype in [lten,gtn]) then
+        current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(ops[unsigned],location.register,tmp_right,left.location.register))
+      else
+        current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(ops[unsigned],location.register,left.location.register,tmp_right));
+    end;
+  if (ntype in [lten,gten]) then
+    current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_XORI,location.register,location.register,1));
 end;
 
-function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
-var
-  lfcmp64_L4, lfcmp64_L5: tasmlabel;
-  tmpreg1,tmpreg2 : TRegister;
-  ai : TaiCpu;
-begin
-  tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
-
-  current_asmdata.getjumplabel(lfcmp64_L4);
-  current_asmdata.getjumplabel(lfcmp64_L5);
-
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, tmpreg2, left_reg.reghi, right_reg.reghi));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reglo, right_reg.reglo));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BA, lfcmp64_L4));
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_lt := tmpreg1;
-end;
 
-function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister;
+procedure tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64;unsigned: boolean);
 var
-  lfcmp64_L4, lfcmp64_L5: tasmlabel;
-  tmpreg1,tmpreg2 : TRegister;
-  ai : TaiCpu;
+  hreg: tregister;
 begin
-  tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
-
-  current_asmdata.getjumplabel(lfcmp64_L4);
-  current_asmdata.getjumplabel(lfcmp64_L5);
-
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, tmpreg2, right_reg.reghi, left_reg.reghi));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
-  ai := Taicpu.op_reg_reg_sym(A_BC, right_reg.reghi, left_reg.reghi, lfcmp64_L5);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reglo, left_reg.reglo));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_le := tmpreg1;
+  hreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(ops[unsigned], hreg, left_reg.reghi, right_reg.reghi));
+  cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrTrueLabel);
+  cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrFalseLabel);
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, hreg, left_reg.reglo, right_reg.reglo));
+  cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrTrueLabel);
+  cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
 end;
 
-function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
+
+procedure tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64;unsigned: boolean);
 var
-  lfcmp64_L4, lfcmp64_L5: tasmlabel;
-  tmpreg1,tmpreg2 : TRegister;
-  ai : TaiCpu;
+  hreg: TRegister;
 begin
-  tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
-
-  current_asmdata.getjumplabel(lfcmp64_L4);
-  current_asmdata.getjumplabel(lfcmp64_L5);
-
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reghi, right_reg.reghi));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reglo, right_reg.reglo));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BA, lfcmp64_L4));
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
-
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_ltu := tmpreg1;
+  hreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(ops[unsigned], hreg, right_reg.reghi, left_reg.reghi));
+  cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrFalseLabel);
+  cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrTrueLabel);
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, hreg, right_reg.reglo, left_reg.reglo));
+  cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrFalseLabel);
+  cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
 end;
 
-function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
+
+procedure tmipsaddnode.second_cmp64bit;
 var
-  lfcmp64_L4, lfcmp64_L5: tasmlabel;
-  tmpreg1,tmpreg2 : TRegister;
-  ai : TaiCpu;
+  unsigned: boolean;
+  left_reg,right_reg: TRegister64;
 begin
-  tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
-
-  current_asmdata.getjumplabel(lfcmp64_L4);
-  current_asmdata.getjumplabel(lfcmp64_L5);
-
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reghi, left_reg.reghi));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
-  ai := Taicpu.op_reg_reg_sym(A_BC, right_reg.reghi, left_reg.reghi, lfcmp64_L5);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reglo, left_reg.reglo));
-  //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
-  ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
-  ai.setCondition(C_NE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
+  location_reset(location, LOC_JUMP, OS_NO);
+  pass_left_right;
+  force_reg_left_right(true,true);
 
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
+  unsigned:=not(is_signed(left.resultdef)) or
+            not(is_signed(right.resultdef));
 
-  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_leu := tmpreg1;
-end;
+  left_reg:=left.location.register64;
+  if (right.location.loc=LOC_CONSTANT) then
+    begin
+      if lo(right.location.value64)=0 then
+        right_reg.reglo:=NR_R0
+      else
+        begin
+          right_reg.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+          cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,lo(right.location.value64),right_reg.reglo);
+        end;
+      if hi(right.location.value64)=0 then
+        right_reg.reghi:=NR_R0
+      else
+        begin
+          right_reg.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+          cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,hi(right.location.value64),right_reg.reghi);
+        end;
+    end
+  else
+    right_reg:=right.location.register64;
 
-function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister;
-                                                            left_reg, right_reg: TRegister64): TRegister;
-var
-  tmpreg: TRegister;
-  lfcmp64_L4, lfcmp_L5: tasmlabel;
-begin
   case NodeType of
     equaln:
-    begin
-      GetRes64_register := cmp64_eq(left_reg, right_reg);
-    end;
+      begin
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrFalseLabel);
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,current_procinfo.CurrFalseLabel);
+        cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
+      end;
     unequaln:
-      GetRes64_register := cmp64_ne(left_reg, right_reg);
-    else
-      if not (unsigned) then
       begin
-        if nf_swapped in flags then
-          case NodeType of
-            ltn:
-              GetRes64_register := cmp64_lt(right_reg, left_reg);
-            lten:
-              GetRes64_register := cmp64_le(right_reg, left_reg);
-            gtn:
-              GetRes64_register := cmp64_lt(left_reg, right_reg);
-            gten:
-              GetRes64_register := cmp64_le(left_reg, right_reg);
-          end
-        else
-          case NodeType of
-            ltn:
-              GetRes64_register := cmp64_lt(left_reg, right_reg);
-            lten:
-              GetRes64_register := cmp64_le(left_reg, right_reg);
-            gtn:
-              GetRes64_register := cmp64_lt(right_reg, left_reg);
-            gten:
-              GetRes64_register := cmp64_le(right_reg, left_reg);
-          end;
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrTrueLabel);
+        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,current_procinfo.CurrTrueLabel);
+        cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
+      end;
+  else
+    if nf_swapped in flags then
+      case NodeType of
+        ltn:
+          cmp64_lt(right_reg, left_reg,unsigned);
+        lten:
+          cmp64_le(right_reg, left_reg,unsigned);
+        gtn:
+          cmp64_lt(left_reg, right_reg,unsigned);
+        gten:
+          cmp64_le(left_reg, right_reg,unsigned);
       end
-      else
-      begin
-        if nf_swapped in Flags then
-          case NodeType of
-            ltn:
-              GetRes64_register := cmp64_ltu(right_reg, left_reg);
-            lten:
-              GetRes64_register := cmp64_leu(right_reg, left_reg);
-            gtn:
-              GetRes64_register := cmp64_ltu(left_reg, right_reg);
-            gten:
-              GetRes64_register := cmp64_leu(left_reg, right_reg);
-          end
-        else
-          case NodeType of
-            ltn:
-              GetRes64_register := cmp64_ltu(left_reg, right_reg);
-            lten:
-              GetRes64_register := cmp64_leu(left_reg, right_reg);
-            gtn:
-              GetRes64_register := cmp64_ltu(right_reg, left_reg);
-            gten:
-              GetRes64_register := cmp64_leu(right_reg, left_reg);
-          end;
+    else
+      case NodeType of
+        ltn:
+          cmp64_lt(left_reg, right_reg,unsigned);
+        lten:
+          cmp64_le(left_reg, right_reg,unsigned);
+        gtn:
+          cmp64_lt(right_reg, left_reg,unsigned);
+        gten:
+          cmp64_le(right_reg, left_reg,unsigned);
       end;
   end;
 end;
 
 
 function tmipsaddnode.pass_1 : tnode;
-  var
-    unsigned : boolean;
   begin
     result:=inherited pass_1;
 
     if not(assigned(result)) then
       begin
         if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) then
-          expectloc:=LOC_REGISTER;
+          begin
+            if (left.resultdef.typ=floatdef) or (right.resultdef.typ=floatdef) then
+              expectloc:=LOC_JUMP
+            else if ((left.resultdef.typ<>orddef) or
+              (not (torddef(left.resultdef).ordtype in [s64bit,u64bit,scurrency]))) then
+              expectloc:=LOC_REGISTER;
+          end;
       end;
   end;
 
@@ -488,197 +332,69 @@ begin
 end;
 
 
+const
+  ops_cmpfloat: array[boolean,ltn..unequaln] of TAsmOp = (
+  // ltn       lten      gtn       gten      equaln    unequaln
+    (A_C_LT_S, A_C_LE_S, A_C_LT_S, A_C_LE_S, A_C_EQ_S, A_C_EQ_S),
+    (A_C_LT_D, A_C_LE_D, A_C_LT_D, A_C_LE_D, A_C_EQ_D, A_C_EQ_D)
+  );
+
 procedure tmipsaddnode.second_cmpfloat;
 var
-  op: tasmop;
-  lfcmptrue, lfcmpfalse: tasmlabel;
+  op,op2: tasmop;
+  lreg,rreg: tregister;
 begin
   pass_left_right;
   if nf_swapped in flags then
     swapleftright;
 
-  { force fpureg as location, left right doesn't matter
-    as both will be in a fpureg }
   location_force_fpureg(current_asmdata.CurrAsmList, left.location, True);
   location_force_fpureg(current_asmdata.CurrAsmList, right.location, True);
+  location_reset(location, LOC_JUMP, OS_NO);
 
-  location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
+  op:=ops_cmpfloat[left.location.size=OS_F64,nodetype];
 
-  case NodeType of
-    equaln:
-    begin
-      if left.location.size = OS_F64 then
-        op := A_C_EQ_D
-      else
-        op := A_C_EQ_S;
-      current_asmdata.getjumplabel(lfcmpfalse);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register , NR_R0, NR_R0));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
-      current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse)); //lfcmpfalse
-      current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
-      cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
+  if (nodetype=unequaln) then
+    op2:=A_BC1F
+  else
+    op2:=A_BC1T;
 
-    end;
-    unequaln:
+  if (nodetype in [gtn,gten]) then
     begin
-      if left.location.size = OS_F64 then
-        op := A_C_EQ_D
-      else
-        op := A_C_EQ_S;
-      current_asmdata.getjumplabel(lfcmpfalse);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
-      current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse));
-      current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register , NR_R0, NR_R0));
-      cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
-    end;
-    ltn:
-    begin
-      if left.location.size = OS_F64 then
-        op := A_C_LT_D
-      else
-        op := A_C_LT_S;
-      current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
-      current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
-      current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
-      cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
-    end;
-    lten:
-    begin
-      if left.location.size = OS_F64 then
-        op := A_C_LE_D
-      else
-        op := A_C_LE_S;
-      current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
-      current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
-      current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
-      cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
-    end;
-    gtn:
-    begin
-      if left.location.size = OS_F64 then
-        op := A_C_LT_D
-      else
-        op := A_C_LT_S;
-      current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register));
-      current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
-      current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
-      cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
-    end;
-    gten:
+      lreg:=right.location.register;
+      rreg:=left.location.register;
+    end
+  else
     begin
-      if left.location.size = OS_F64 then
-        op := A_C_LE_D
-      else
-        op := A_C_LE_S;
-      current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register));
-      current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
-      current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
-      cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
+      lreg:=left.location.register;
+      rreg:=right.location.register;
     end;
-  end; {case}
+
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,lreg,rreg));
+  current_asmdata.CurrAsmList.concat(Taicpu.op_sym(op2,current_procinfo.CurrTrueLabel));
+  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
+  cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
 end;
 
 
 procedure tmipsaddnode.second_cmpboolean;
-var
-  tmp_right_reg, tmpreg: TRegister;
 begin
-  pass_left_right;
-  force_reg_left_right(True, True);
-  tmp_right_reg := NR_NO;
-  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  if right.location.loc = LOC_CONSTANT then
-    begin
-      tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
-    end
-  else
-    tmp_right_reg := right.location.Register;
-
-  location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg);
+  second_generic_cmp32(true);
 end;
 
 
 procedure tmipsaddnode.second_cmpsmallset;
-var
-  tmp_right_reg, tmpreg: TRegister;
 begin
-  pass_left_right;
-  force_reg_left_right(True, True);
-
-  tmp_right_reg := NR_NO;
-  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-
-  if right.location.loc = LOC_CONSTANT then
-  begin
-    tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-    current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
-  end
-  else
-  begin
-    tmp_right_reg := right.location.Register;
-  end;
-
-
-  location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg);
-end;
-
-
-procedure tmipsaddnode.second_cmp64bit;
-var
-         unsigned   : boolean;
-  tmp_left_reg: TRegister;
-
-begin
-  pass_left_right;
-  force_reg_left_right(false,false);
-
-  unsigned:=not(is_signed(left.resultdef)) or
-            not(is_signed(right.resultdef));
-
-  location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := GetRes64_register(unsigned, left.location.register64, right.location.register64); 
+  second_generic_cmp32(true);
 end;
 
 
 procedure tmipsaddnode.second_cmpordinal;
 var
   unsigned: boolean;
-  tmp_right_reg,tmpreg: TRegister;
 begin
-  pass_left_right;
-  force_reg_left_right(True, True);
   unsigned := not (is_signed(left.resultdef)) or not (is_signed(right.resultdef));
-
-  tmp_right_reg := NR_NO;
-  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-  if right.location.loc = LOC_CONSTANT then
-    begin
-      tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
-    end
-  else
-    tmp_right_reg := right.location.Register;
-  location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := getres_register(unsigned, tmpreg, left.location.Register, tmp_right_reg);
+  second_generic_cmp32(unsigned);
 end;
 
 begin