From 93e0dd9c2faaaa5c2447933585d7cdeab65c4995 Mon Sep 17 00:00:00 2001
From: pierre <pierre@freepascal.org>
Date: Thu, 7 Jun 2012 23:20:06 +0000
Subject: [PATCH]  * Patch from Fuxin Zhang: other mips and mipsel CPUs changes

git-svn-id: trunk@21538 -
---
 compiler/mips/aasmcpu.pas  |  17 +-
 compiler/mips/aoptcpub.pas |   4 +-
 compiler/mips/cgcpu.pas    | 312 ++++++++++++++++---------------------
 compiler/mips/cpubase.pas  |  37 ++---
 compiler/mips/cpugas.pas   |  44 ++++--
 compiler/mips/ncpuadd.pas  | 206 ++++++++++++++++--------
 compiler/mips/ncpucnv.pas  |  94 +++++++----
 compiler/mips/ncpumat.pas  |   6 +-
 compiler/mips/opcode.inc   |  40 +----
 compiler/mips/racpugas.pas |   2 +-
 compiler/mips/strinst.inc  |  38 +----
 11 files changed, 397 insertions(+), 403 deletions(-)

diff --git a/compiler/mips/aasmcpu.pas b/compiler/mips/aasmcpu.pas
index 67c1e4335f..065e23d67f 100644
--- a/compiler/mips/aasmcpu.pas
+++ b/compiler/mips/aasmcpu.pas
@@ -195,12 +195,7 @@ end;
 constructor taicpu.op_sym(op: tasmop; _op1: tasmsymbol);
 begin
   inherited Create(op);
-  is_jmp := op in [A_J, A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI,
-    A_BLTUI, A_BLEUI, A_BGTUI, A_BGEUI,
-    A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE,
-    A_BLTU, A_BLEU, A_BGTU, A_BGEU
-    ];
-
+  is_jmp := op in [A_BC, A_BA];
   ops := 1;
   loadsymbol(0, _op1, 0);
 end;
@@ -208,10 +203,7 @@ end;
 constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
 begin
    inherited create(op);
-   is_jmp := op in [A_J,
-     A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI,
-     A_BGTUI, A_BGEUI,
-     A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU];
+   is_jmp := op in [A_BC, A_BA];
    ops := 3;
    loadreg(0, _op1);
    loadreg(1, _op2);
@@ -221,10 +213,7 @@ end;
 constructor taicpu.op_reg_sym(op: tasmop; _op1: tregister; _op2: tasmsymbol);
 begin
    inherited create(op);
-   is_jmp := op in [A_J,
-     A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI,
-     A_BGTUI, A_BGEUI,
-     A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU, A_BGTZ];
+   is_jmp := op in [A_BC, A_BA];
    ops := 2;
    loadreg(0, _op1);
    loadsymbol(1, _op2, 0);
diff --git a/compiler/mips/aoptcpub.pas b/compiler/mips/aoptcpub.pas
index c758c914b0..ed51361166 100644
--- a/compiler/mips/aoptcpub.pas
+++ b/compiler/mips/aoptcpub.pas
@@ -93,8 +93,8 @@ Const
 
   StoreDst = 1;
 
-  aopt_uncondjmp = A_J;
-  aopt_condjmp = A_BEQ;
+  aopt_uncondjmp = A_BA;
+  aopt_condjmp = A_BC;
 
 Implementation
 
diff --git a/compiler/mips/cgcpu.pas b/compiler/mips/cgcpu.pas
index 2523761f04..d4780d777f 100644
--- a/compiler/mips/cgcpu.pas
+++ b/compiler/mips/cgcpu.pas
@@ -27,7 +27,7 @@ interface
 
 uses
   globtype, parabase,
-  cgbase, cgutils, cgobj, cg64f32,
+  cgbase, cgutils, cgobj, cg64f32, cpupara,
   aasmbase, aasmtai, aasmcpu, aasmdata,
   cpubase, cpuinfo,
   node, symconst, SymType, symdef,
@@ -36,6 +36,7 @@ uses
 type
   TCGMIPS = class(tcg)
   public
+
     procedure init_register_allocators; override;
     procedure done_register_allocators; override;
     function getfpuregister(list: tasmlist; size: Tcgsize): Tregister; override;
@@ -106,6 +107,11 @@ type
 
   procedure create_codegen;
 
+  const
+      TOpCmp2AsmCond : array[topcmp] of TAsmCond=(C_NONE,
+        C_EQ,C_GT,C_LT,C_GE,C_LE,C_NE,C_LEU,C_LTU,C_GEU,C_GTU
+      );
+
 implementation
 
 uses
@@ -311,7 +317,7 @@ begin
   if (cs_create_pic in current_settings.moduleswitches) and
     assigned(ref.symbol) then
   begin
-    tmpreg := GetIntRegister(list, OS_INT);
+    tmpreg := cg.GetIntRegister(list, OS_INT);
     reference_reset(tmpref,sizeof(aint));
     tmpref.symbol  := ref.symbol;
     tmpref.refaddr := addr_pic;
@@ -518,12 +524,18 @@ begin
        RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25],
       first_int_imreg, []);
 
+{
   rg[R_FPUREGISTER] := trgcpu.Create(R_FPUREGISTER, R_SUBFS,
     [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7,
      RS_F8,RS_F9,RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,
      RS_F16,RS_F17,RS_F18,RS_F19,RS_F20,RS_F21,RS_F22,RS_F23,
      RS_F24,RS_F25,RS_F26,RS_F27,RS_F28,RS_F29,RS_F30,RS_F31],
     first_fpu_imreg, []);
+}
+  rg[R_FPUREGISTER] := trgcpu.Create(R_FPUREGISTER, R_SUBFS,
+    [RS_F0,RS_F2,RS_F4,RS_F6, RS_F8,RS_F10,RS_F12,RS_F14,
+     RS_F16,RS_F18,RS_F20,RS_F22, RS_F24,RS_F26,RS_F28,RS_F30],
+    first_fpu_imreg, []);
 
   { needs at least one element for rgobj not to crash }
   rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
@@ -1235,6 +1247,7 @@ end;
 procedure TCGMIPS.a_cmp_const_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
 var
   tmpreg: tregister;
+  ai : Taicpu;
 begin
 if a = 0 then
   tmpreg := NR_R0
@@ -1243,75 +1256,37 @@ begin
   tmpreg := GetIntRegister(list, OS_INT);
   list.concat(taicpu.op_reg_const(A_LI, tmpreg, a));
 end;
-  case cmp_op of
-    OC_EQ:           { equality comparison              }
-      list.concat(taicpu.op_reg_reg_sym(A_BEQ, reg, tmpreg, l));
-    OC_GT:           { greater than (signed)            }
-      list.concat(taicpu.op_reg_reg_sym(A_BGT, reg, tmpreg, l));
-    OC_LT:           { less than (signed)               }
-      list.concat(taicpu.op_reg_reg_sym(A_BLT, reg, tmpreg, l));
-    OC_GTE:          { greater or equal than (signed)   }
-      list.concat(taicpu.op_reg_reg_sym(A_BGE, reg, tmpreg, l));
-    OC_LTE:          { less or equal than (signed)      }
-      list.concat(taicpu.op_reg_reg_sym(A_BLE, reg, tmpreg, l));
-    OC_NE:           { not equal                        }
-      list.concat(taicpu.op_reg_reg_sym(A_BNE, reg, tmpreg, l));
-    OC_BE:           { less or equal than (unsigned)    }
-      list.concat(taicpu.op_reg_reg_sym(A_BLEU, reg, tmpreg, l));
-    OC_B:            { less than (unsigned)             }
-      list.concat(taicpu.op_reg_reg_sym(A_BLTU, reg, tmpreg, l));
-    OC_AE:           { greater or equal than (unsigned) }
-      list.concat(taicpu.op_reg_reg_sym(A_BGEU, reg, tmpreg, l));
-    OC_A:             { greater than (unsigned)          }
-      list.concat(taicpu.op_reg_reg_sym(A_BGTU, reg, tmpreg, l));
-    else
-      internalerror(200701071);
-  end;
+  ai := taicpu.op_reg_reg_sym(A_BC, reg, tmpreg, l);
+  ai.SetCondition(TOpCmp2AsmCond[cmp_op]);
+  list.concat(ai);
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
 
 
 procedure TCGMIPS.a_cmp_reg_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);
+var
+  ai : Taicpu;
 begin
-  case cmp_op of
-    OC_EQ:           { equality comparison              }
-      list.concat(taicpu.op_reg_reg_sym(A_BEQ, reg2, reg1, l));
-    OC_GT:           { greater than (signed)            }
-      list.concat(taicpu.op_reg_reg_sym(A_BGT, reg2, reg1, l));
-    OC_LT:           { less than (signed)               }
-      list.concat(taicpu.op_reg_reg_sym(A_BLT, reg2, reg1, l));
-    OC_GTE:          { greater or equal than (signed)   }
-      list.concat(taicpu.op_reg_reg_sym(A_BGE, reg2, reg1, l));
-    OC_LTE:          { less or equal than (signed)      }
-      list.concat(taicpu.op_reg_reg_sym(A_BLE, reg2, reg1, l));
-    OC_NE:           { not equal                        }
-      list.concat(taicpu.op_reg_reg_sym(A_BNE, reg2, reg1, l));
-    OC_BE:           { less or equal than (unsigned)    }
-      list.concat(taicpu.op_reg_reg_sym(A_BLEU, reg2, reg1, l));
-    OC_B:            { less than (unsigned)             }
-      list.concat(taicpu.op_reg_reg_sym(A_BLTU, reg2, reg1, l));
-    OC_AE:           { greater or equal than (unsigned) }
-      list.concat(taicpu.op_reg_reg_sym(A_BGEU, reg2, reg1, l));
-    OC_A:             { greater than (unsigned)          }
-      list.concat(taicpu.op_reg_reg_sym(A_BGTU, reg2, reg1, l));
-    else
-      internalerror(200701072);
-    end;{ case }
+  ai := taicpu.op_reg_reg_sym(A_BC, reg2, reg1, l);
+  ai.SetCondition(TOpCmp2AsmCond[cmp_op]);
+  list.concat(ai);
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
 
 
 procedure TCGMIPS.a_jmp_always(List: tasmlist; l: TAsmLabel);
+var
+  ai : Taicpu;
 begin
-  List.Concat(TAiCpu.op_sym(A_J,l));
-  { Delay slot }
+  ai := taicpu.op_sym(A_BA, l);
+  list.concat(ai);
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
 
 
 procedure TCGMIPS.a_jmp_name(list: tasmlist; const s: string);
 begin
-  List.Concat(TAiCpu.op_sym(A_J, current_asmdata.RefAsmSymbol(s)));
+  List.Concat(TAiCpu.op_sym(A_BA, current_asmdata.RefAsmSymbol(s)));
   { Delay slot }
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
@@ -1341,6 +1316,8 @@ procedure TCGMIPS.g_proc_entry(list: tasmlist; localsize: longint; nostackframe:
 var
   lastintoffset,lastfpuoffset,
   nextoffset : aint;
+  i : longint;
+  ra_save,framesave : taicpu;
   fmask,mask : dword;
   saveregs : tcpuregisterset;
   href:  treference;
@@ -1348,14 +1325,8 @@ var
   reg : Tsuperregister;
   helplist : TAsmList;
 begin
-  {
-  if STK2_dummy <> 0 then
-  begin
-    list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, -STK2_dummy));
-  end;
-  }
   a_reg_alloc(list,NR_STACK_POINTER_REG);
-  if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+  // if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
     a_reg_alloc(list,NR_FRAME_POINTER_REG);
 
   if nostackframe then
@@ -1368,9 +1339,7 @@ begin
   { if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
     list.concat(Taicpu.Op_reg_reg_const(A_P_SW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, -LocalSize));
   }
-  { if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
-      list.concat(Taicpu.op_reg_reg(A_MOVE, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG));
-  }
+
 
   reference_reset(href,0);
   href.base:=NR_STACK_POINTER_REG;
@@ -1397,7 +1366,11 @@ begin
   nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
   saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
   include(saveregs,RS_R31);
+  //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+    include(saveregs,RS_FRAME_POINTER_REG);
   lastintoffset:=LocalSize;
+  framesave:=nil;
+
   for reg:=RS_R1 to RS_R31 do
     begin
       if reg in saveregs then
@@ -1406,24 +1379,67 @@ begin
           mask:=mask or (1 shl ord(reg));
           href.offset:=nextoffset;
           lastintoffset:=nextoffset;
-          helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
+          if (reg=RS_FRAME_POINTER_REG) then
+            framesave:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
+          else if (reg=RS_R31) then
+            ra_save:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
+          else
+            helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
           inc(nextoffset,4);
         end;
     end;
 
+  //list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,current_procinfo.para_stack_size));
   list.concat(Taicpu.op_none(A_P_SET_NOMIPS16));
-  list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31));
+  list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,NR_STACK_POINTER_REG,LocalSize,NR_R31));
   list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset)));
   list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset)));
   list.concat(Taicpu.op_none(A_P_SET_NOREORDER));
   list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
 
   if (-LocalSize >= simm16lo) and (-LocalSize <= simm16hi) then
-    list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize))
+    begin
+      list.concat(Taicpu.Op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize));
+      list.concat(ra_save);
+      //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+        begin
+          list.concat(framesave);
+          list.concat(Taicpu.op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,
+            NR_STACK_POINTER_REG,LocalSize));
+        end;
+    end
   else
     begin
       list.concat(Taicpu.Op_reg_const(A_LI,NR_R3,-LocalSize));
       list.concat(Taicpu.Op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R3));
+      list.concat(ra_save);
+      //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+        begin
+          list.concat(framesave);
+          list.concat(Taicpu.op_reg_reg_reg(A_SUB,NR_FRAME_POINTER_REG,
+            NR_STACK_POINTER_REG,NR_R3));
+        end;
+    end;
+
+  with TMIPSProcInfo(current_procinfo) do
+    begin
+      href.offset:=0;
+      //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+        href.base:=NR_FRAME_POINTER_REG;
+
+      for i:=0 to MIPS_MAX_REGISTERS_USED_IN_CALL-1 do
+        if (register_used[i]) then
+          begin
+            reg:=parainsupregs[i];
+            if register_offset[i]=-1 then
+              comment(V_warning,'Register parameter has offset -1 in TCGMIPS.g_proc_entry');
+
+            //if current_procinfo.framepointer=NR_STACK_POINTER_REG then
+            //  href.offset:=register_offset[i]+Localsize
+            //else
+              href.offset:=register_offset[i];
+            list.concat(taicpu.op_reg_ref(A_SW, newreg(R_INTREGISTER,reg,R_SUBWHOLE), href));
+          end;
     end;
 
   if (cs_create_pic in current_settings.moduleswitches) and
@@ -1447,9 +1463,6 @@ begin
   stacksize:=current_procinfo.calc_stackframe_size;
    if nostackframe then
      begin
-       { if STK2_dummy <> 0 then
-         list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy));
-       }
        list.concat(taicpu.op_reg(A_J, NR_R31));
        list.concat(Taicpu.op_none(A_NOP));
        list.concat(Taicpu.op_none(A_P_SET_MACRO));
@@ -1474,12 +1487,14 @@ begin
        nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
        saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
        include(saveregs,RS_R31);
+       //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+         include(saveregs,RS_FRAME_POINTER_REG);
        for reg:=RS_R1 to RS_R31 do
          begin
            if reg in saveregs then
              begin
                href.offset:=nextoffset;
-               list.concat(taicpu.op_reg_ref(A_LD,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
+               list.concat(taicpu.op_reg_ref(A_LW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
                inc(nextoffset,sizeof(aint));
              end;
          end;
@@ -1539,6 +1554,7 @@ var
   src, dst: TReference;
   lab:      tasmlabel;
   Count, count2: aint;
+  ai : TaiCpu;
 begin
   if len > high(longint) then
     internalerror(2002072704);
@@ -1575,7 +1591,10 @@ begin
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, src.base, src.base, 4));
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, dst.base, dst.base, 4));
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, countreg, countreg, -1));
-      list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
+      //list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
+      ai := taicpu.op_reg_reg_sym(A_BC,countreg, NR_R0, lab);
+      ai.setcondition(C_GT);
+      list.concat(ai);
       list.concat(taicpu.op_none(A_NOP));
       len := len mod 4;
     end;
@@ -1626,6 +1645,7 @@ var
   tmpreg1, countreg: TRegister;
   i:   aint;
   lab: tasmlabel;
+  ai : TaiCpu;
 begin
   if len > 31 then
     g_concatcopy_move(list, Source, dest, len)
@@ -1646,8 +1666,8 @@ begin
       { have to be set to 8. I put an Inc there so debugging may be   }
       { easier (should offset be different from zero here, it will be }
       { easy to notice in the generated assembler                     }
-      countreg := GetIntRegister(list, OS_INT);
-      tmpreg1  := GetIntRegister(list, OS_INT);
+      countreg := cg.GetIntRegister(list, OS_INT);
+      tmpreg1  := cg.GetIntRegister(list, OS_INT);
       a_load_const_reg(list, OS_INT, len, countreg);
       { explicitely allocate R_O0 since it can be used safely here }
       { (for holding date that's being copied)                    }
@@ -1658,13 +1678,16 @@ begin
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, src.base, src.base, 1));
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, dst.base, dst.base, 1));
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, countreg, countreg, -1));
-      list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
+      //list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
+      ai := taicpu.op_reg_reg_sym(A_BC,countreg, NR_R0, lab);
+      ai.setcondition(C_GT);
+      list.concat(ai);
       list.concat(taicpu.op_none(A_NOP));
     end
     else
     begin
       { unrolled loop }
-      tmpreg1 := GetIntRegister(list, OS_INT);
+      tmpreg1 := cg.GetIntRegister(list, OS_INT);
       for i := 1 to len do
       begin
         list.concat(taicpu.op_reg_ref(A_LBU, tmpreg1, src));
@@ -1679,25 +1702,25 @@ end;
 
 procedure TCGMIPS.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const labelname: string; ioffset: longint);
 
-  procedure loadvmttor24;
+  procedure loadvmttor25;
     var
       href: treference;
     begin
       reference_reset_base(href, NR_R2, 0, sizeof(aint));  { return value }
-      cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24);
+      cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25);
     end;
 
 
-   procedure op_onr24methodaddr;
+   procedure op_onr25methodaddr;
      var
        href : treference;
      begin
        if (procdef.extnumber=$ffff) then
          Internalerror(200006139);
        { call/jmp  vmtoffs(%eax) ; method offs }
-       reference_reset_base(href, NR_R24, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint));
-       cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24);
-       list.concat(taicpu.op_reg(A_JR, NR_R24));
+       reference_reset_base(href, NR_R25, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint));
+       cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25);
+       list.concat(taicpu.op_reg(A_JR, NR_R25));
      end;
 var
   make_global: boolean;
@@ -1728,8 +1751,8 @@ begin
   if (po_virtualmethod in procdef.procoptions) and
       not is_objectpascal_helper(procdef.struct) then
   begin
-    loadvmttor24;
-    op_onr24methodaddr;
+    loadvmttor25;
+    op_onr25methodaddr;
   end
   else
    list.concat(taicpu.op_sym(A_J,current_asmdata.RefAsmSymbol(procdef.mangledname)));
@@ -1790,26 +1813,21 @@ begin
   a_load64_reg_cgpara(list, hreg64, paraloc);
 end;
 
-
-
-
 procedure TCg64MPSel.a_op64_reg_reg(list: tasmlist; op: TOpCG; size: tcgsize; regsrc, regdst: TRegister64);
 var
   op1, op2, op_call64: TAsmOp;
   tmpreg1, tmpreg2: TRegister;
 begin
-  tmpreg1 := NR_TCR12; //GetIntRegister(list, OS_INT);
-  tmpreg2 := NR_TCR13; //GetIntRegister(list, OS_INT);
+  tmpreg1 := cg.GetIntRegister(list, OS_INT);
+  tmpreg2 := cg.GetIntRegister(list, OS_INT);
 
   case op of
     OP_ADD:
       begin
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, regsrc.reglo, regdst.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, tmpreg1, regsrc.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc.reglo, regdst.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc.reglo));
         list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg2, regsrc.reghi, regdst.reghi));
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, NR_TCR10, NR_TCR10, tmpreg2));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, NR_TCR10));
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, tmpreg1, tmpreg2));
         exit;
       end;
     OP_AND:
@@ -1822,10 +1840,10 @@ begin
     OP_NEG:
       begin
         list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, NR_R0, regsrc.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, NR_R0, regdst.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, NR_R0, regdst.reglo));
         list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, NR_R0, regsrc.reghi));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, NR_TCR10, regdst.reghi, NR_TCR10));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, NR_TCR10));
+        list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reghi, tmpreg1));
+        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1));
         exit;
       end;
     OP_NOT:
@@ -1843,11 +1861,10 @@ begin
     OP_SUB:
     begin
         list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reglo, regsrc.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, regdst.reglo, tmpreg1));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, regdst.reghi, regsrc.reghi));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, tmpreg2, NR_TCR10));
+        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, regdst.reglo, tmpreg1));
+        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, regsrc.reghi));
+        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, tmpreg2));
         list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg2));
         exit;
     end;
     OP_XOR:
@@ -1860,26 +1877,14 @@ begin
       internalerror(200306017);
 
   end; {case}
-
-
-
 end;
 
 
 procedure TCg64MPSel.a_op64_const_reg(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regdst: TRegister64);
-var
-  op1, op2: TAsmOp;
 begin
-  case op of
-    OP_NEG,
-    OP_NOT:
-      internalerror(200306017);
-  end;
   a_op64_const_reg_reg(list, op, size, value, regdst, regdst);
-
 end;
 
-
 procedure TCg64MPSel.a_op64_const_reg_reg(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regsrc, regdst: tregister64);
 var
   l: tlocation;
@@ -1898,59 +1903,15 @@ end;
 
 procedure TCg64MPSel.a_op64_const_reg_reg_checkoverflow(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regsrc, regdst: tregister64; setflags: boolean; var ovloc: tlocation);
 var
-  op1, op2: TAsmOp;
-  tmpreg1: TRegister;
+  tmpreg64: TRegister64;
 begin
-  tmpreg1 := NR_TCR12;
-  case op of
-    OP_NEG,
-    OP_NOT:
-      internalerror(200306017);
-  end;
+  tmpreg64.reglo := cg.GetIntRegister(list, OS_S32);
+  tmpreg64.reghi := cg.GetIntRegister(list, OS_S32);
 
-  list.concat(taicpu.op_reg_const(A_LI, NR_TCR10, aint(hi(Value))));
-  list.concat(taicpu.op_reg_const(A_LI, NR_TCR11, aint(lo(Value))));
-  case op of
-    OP_ADD:
-      begin
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc.reglo, NR_TCR10));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regsrc.reghi, NR_TCR11));
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, tmpreg1, regdst.reghi));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1));
-        exit;
-      end;
-    OP_AND:
-    begin
-        list.concat(taicpu.op_reg_reg_reg(A_AND, regdst.reglo, regsrc.reglo, NR_TCR10));
-        list.concat(taicpu.op_reg_reg_reg(A_AND, regdst.reghi, regsrc.reghi, NR_TCR11));
-        exit;
-    end;
+  list.concat(taicpu.op_reg_const(A_LI, tmpreg64.reglo, aint(lo(Value))));
+  list.concat(taicpu.op_reg_const(A_LI, tmpreg64.reghi, aint(hi(Value))));
 
-    OP_OR:
-    begin
-        list.concat(taicpu.op_reg_reg_reg(A_OR, regdst.reglo, regsrc.reglo, NR_TCR10));
-        list.concat(taicpu.op_reg_reg_reg(A_OR, regdst.reghi, regsrc.reghi, NR_TCR11));
-        exit;
-    end;
-    OP_SUB:
-    begin
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, regsrc.reglo, NR_TCR10));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regsrc.reglo, regdst.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regsrc.reghi, NR_TCR11));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reghi, tmpreg1));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1));
-        exit;
-    end;
-    OP_XOR:
-    begin
-        list.concat(taicpu.op_reg_reg_reg(A_XOR, regdst.reglo, regsrc.reglo, NR_TCR10));
-        list.concat(taicpu.op_reg_reg_reg(A_XOR, regdst.reghi, regsrc.reghi, NR_TCR11));
-        exit;
-    end;
-    else
-      internalerror(200306017);
-  end;
+  a_op64_reg_reg_reg_checkoverflow(list, op, size, tmpreg64, regsrc, regdst, False, ovloc);
 
 end;
 
@@ -1961,22 +1922,15 @@ var
   tmpreg1, tmpreg2: TRegister;
 
 begin
-  tmpreg1 := NR_TCR12;
-  tmpreg2 := NR_TCR13;
 
-  case op of
-    OP_NEG,
-    OP_NOT:
-      internalerror(200306017);
-  end;
   case op of
     OP_ADD:
       begin
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, regsrc2.reglo, regsrc1.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, tmpreg1, regsrc2.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg2, regsrc2.reghi, regsrc1.reghi));
-        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, NR_TCR10, tmpreg2));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
+        tmpreg1 := cg.GetIntRegister(list,OS_S32);
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc2.reglo, regsrc1.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc2.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regsrc2.reghi, regsrc1.reghi));
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regdst.reghi, tmpreg1));
         exit;
       end;
     OP_AND:
@@ -1993,11 +1947,11 @@ begin
     end;
     OP_SUB:
     begin
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regsrc2.reglo, regsrc1.reglo));
-        list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, regsrc2.reglo, tmpreg1));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, regsrc2.reghi, regsrc1.reghi));
-        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, tmpreg2, NR_TCR10));
-        list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
+        tmpreg1 := cg.GetIntRegister(list,OS_S32);
+        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, regsrc2.reglo, regsrc1.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regsrc2.reglo, regdst.reglo));
+        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regsrc2.reghi, regsrc1.reghi));
+        list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, tmpreg1));
         exit;
     end;
     OP_XOR:
diff --git a/compiler/mips/cpubase.pas b/compiler/mips/cpubase.pas
index 29c73d8f35..76ef839b19 100644
--- a/compiler/mips/cpubase.pas
+++ b/compiler/mips/cpubase.pas
@@ -181,7 +181,6 @@ unit cpubase;
                           Generic Register names
 *****************************************************************************}
 
-      STK2_PTR = NR_R23;
       NR_GP = NR_R28;
       NR_SP = NR_R29;
       NR_S8 = NR_R30;
@@ -228,14 +227,6 @@ unit cpubase;
       NR_FPU_RESULT_REG = NR_F0;
       NR_MM_RESULT_REG  = NR_NO;
 
-      NR_TCR0 = NR_R15;
-      NR_TCR1 = NR_R3;
-
-      NR_TCR10 = NR_R20;
-      NR_TCR11 = NR_R21;
-      NR_TCR12 = NR_R18;
-      NR_TCR13 = NR_R19;
-
 
 {*****************************************************************************
                        GCC /ABI linking information
@@ -287,10 +278,6 @@ unit cpubase;
     function std_regnum_search(const s:string):Tregister;
     function std_regname(r:Tregister):string;
 
-    var
-      STK2_dummy: aint;
-      STK2_Localsize: aint;
-
   implementation
 
     uses
@@ -342,27 +329,25 @@ unit cpubase;
       begin
         { This isn't 100% perfect because the arm allows jumps also by writing to PC=R15.
           To overcome this problem we simply forbid that FPC generates jumps by loading R15 }
-        is_calljmp:= o in [A_J,A_JAL,A_JALR,{ A_JALX, }A_JR,
-          A_BEQ,A_BNE,A_BGEZ,A_BGEZAL,A_BGTZ,A_BLEZ,A_BLTZ,A_BLTZAL,
-          A_BEQL,A_BGEZALL,A_BGEZL,A_BGTZL,A_BLEZL,A_BLTZALL,A_BLTZL,A_BNEL];
+        is_calljmp:= o in [A_J,A_JAL,A_JALR,{ A_JALX, }A_JR, A_BA, A_BC, A_BC1T, A_BC1F];
       end;
 
 
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       const
         inverse: array[TAsmCond] of TAsmCond=(C_None,
-        C_EQ, C_NE, C_LT, C_LE, C_GT, C_GE, C_LTU, C_LEU, C_GTU, C_GEU,
-        C_FEQ,  {Equal}
-        C_FNE, {Not Equal}
-        C_FGT,  {Greater}
-        C_FLT,  {Less}
-        C_FGE, {Greater or Equal}
-        C_FLE  {Less or Equal}
-
+        C_NE, C_EQ, C_GE, C_GT, C_LE, C_LT, C_GEU, C_GTU, C_LEU, C_LTU,
+        C_FNE, 
+        C_FEQ, 
+        C_FLE, 
+        C_FGE, 
+        C_FLT, 
+        C_FGT  
         );
       begin
         result := inverse[c];
-      end;      function findreg_by_number(r:Tregister):tregisterindex;
+      end;      
+      function findreg_by_number(r:Tregister):tregisterindex;
       begin
         result:=rgBase.findreg_by_number_table(r,regnumber_index);
       end;
@@ -393,6 +378,4 @@ unit cpubase;
 
 
 begin
-  STK2_dummy := 10;
-  STK2_Localsize := 0;
 end.
diff --git a/compiler/mips/cpugas.pas b/compiler/mips/cpugas.pas
index a4844ae121..8bea6f4ac4 100644
--- a/compiler/mips/cpugas.pas
+++ b/compiler/mips/cpugas.pas
@@ -150,6 +150,27 @@ unit cpugas;
           end;
       end;
 
+{
+     function getnextfpreg(tmpfpu : shortstring) : shortstring;
+     begin
+       case length(tmpfpu) of
+       3:
+        if (tmpfpu[3] = '9') then
+          tmpfpu:='$f10'
+        else
+          tmpfpu[3] := succ(tmpfpu[3]);
+       4:
+        if (tmpfpu[4] = '9') then
+          tmpfpu:='$f20'
+        else
+          tmpfpu[4] := succ(tmpfpu[4]);
+        else
+          internalerror(20120531);
+        end;
+        getnextfpreg := tmpfpu;
+     end;
+}
+
 
     procedure TMIPSInstrWriter.WriteInstruction(hp: Tai);
       var
@@ -158,23 +179,13 @@ unit cpugas;
         i:  integer;
         tmpfpu: string;
         tmpfpu_len: longint;
+        r: TRegister;
       begin
         if hp.typ <> ait_instruction then
           exit;
         op := taicpu(hp).opcode;
 
         case op of
-          A_P_STK2:
-            begin
-              s1 := getopstr(taicpu(hp).oper[2]^);
-              STK2_LocalSize := align(STK2_LocalSize, 8);
-              if s1[1] = '-' then
-                str(-STK2_LocalSize, s1)
-              else
-                str(STK2_LocalSize, s1);
-              s := #9 + gas_op2str[A_ADDIU] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[1]^) + ',' + s1;
-              owner.AsmWriteLn(s);
-            end;
           A_P_SET_NOMIPS16:
             begin
               s := #9 + '.set' + #9 + 'nomips16';
@@ -222,8 +233,14 @@ unit cpugas;
               s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
               owner.AsmWriteLn(s);
 
+{ bug if $f9/$f19
               tmpfpu_len := length(tmpfpu);
               tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]);
+              
+}
+              r := taicpu(hp).oper[0]^.reg;
+              setsupreg(r, getsupreg(r) + 1);
+              tmpfpu := gas_regname(r);
               s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
               owner.AsmWriteLn(s);
             end;
@@ -233,8 +250,13 @@ unit cpugas;
               s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
               owner.AsmWriteLn(s);
 
+{ 
               tmpfpu_len := length(tmpfpu);
               tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]);
+}
+              r := taicpu(hp).oper[0]^.reg;
+              setsupreg(r, getsupreg(r) + 1);
+              tmpfpu := gas_regname(r);
               s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
               owner.AsmWriteLn(s);
             end;
diff --git a/compiler/mips/ncpuadd.pas b/compiler/mips/ncpuadd.pas
index 8d88ce49ca..06dcd85ada 100644
--- a/compiler/mips/ncpuadd.pas
+++ b/compiler/mips/ncpuadd.pas
@@ -137,145 +137,216 @@ end;
 function tmipsaddnode.cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
 var
   lfcmp64_L4: tasmlabel;
+  tmpreg : TRegister;
+  ai : TaiCpu;
 begin
 
+  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
   current_asmdata.getjumplabel(lfcmp64_L4);
 
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0));
 
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
-  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.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_const(A_LI, NR_TCR10, 1));
+  //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 := NR_TCR10;
+  cmp64_eq := tmpreg;
 end;
 
 function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
 var
   lfcmp64_L4: tasmlabel;
+  tmpreg : TRegister;
+  ai : TaiCpu;
 begin
 
+  tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
   current_asmdata.getjumplabel(lfcmp64_L4);
 
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
+  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));
-  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));
+  //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_const(A_LI, NR_TCR10, 0));
+  //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, 0));
 
   cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_ne := NR_TCR10;
+  cmp64_ne := tmpreg;
 end;
 
 function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
 var
   lfcmp64_L4, lfcmp64_L5: tasmlabel;
+  tmpreg1,tmpreg2 : TRegister;
+  ai : TaiCpu;
 begin
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+  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, NR_TCR11, left_reg.reghi, right_reg.reghi));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, 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));
+  //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, NR_TCR11, left_reg.reglo, right_reg.reglo));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
+  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_B, lfcmp64_L4));
+  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, NR_TCR10, 1));
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
 
   cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_lt := NR_TCR10;
+  cmp64_lt := tmpreg1;
 end;
 
 function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister;
 var
   lfcmp64_L4, lfcmp64_L5: tasmlabel;
+  tmpreg1,tmpreg2 : TRegister;
+  ai : TaiCpu;
 begin
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+  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, NR_TCR11, right_reg.reghi, left_reg.reghi));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
+  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));
+  //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, NR_TCR11, right_reg.reglo, left_reg.reglo));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
+  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, NR_TCR10, 1));
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
 
   cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_le := NR_TCR10;
+  cmp64_le := tmpreg1;
 end;
 
 function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
 var
   lfcmp64_L4, lfcmp64_L5: tasmlabel;
+  tmpreg1,tmpreg2 : TRegister;
+  ai : TaiCpu;
 begin
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+  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, NR_TCR11, left_reg.reghi, right_reg.reghi));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, 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));
+  //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, NR_TCR11, left_reg.reglo, right_reg.reglo));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
+  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_B, lfcmp64_L4));
+  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, NR_TCR10, 1));
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
 
   cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_ltu := NR_TCR10;
+  cmp64_ltu := tmpreg1;
 end;
 
 function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
 var
   lfcmp64_L4, lfcmp64_L5: tasmlabel;
+  tmpreg1,tmpreg2 : TRegister;
+  ai : TaiCpu;
 begin
-  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+  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, NR_TCR11, right_reg.reghi, left_reg.reghi));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
+  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));
+  //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, NR_TCR11, right_reg.reglo, left_reg.reglo));
-  current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
+  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, NR_TCR10, 1));
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
 
   cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
-  cmp64_leu := NR_TCR10;
+  cmp64_leu := tmpreg1;
 end;
 
 function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister;
@@ -432,7 +503,7 @@ begin
   location_force_fpureg(current_asmdata.CurrAsmList, right.location, True);
 
   location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := NR_TCR0;
+  location.Register := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
 
   case NodeType of
     equaln:
@@ -442,11 +513,11 @@ begin
       else
         op := A_C_EQ_S;
       current_asmdata.getjumplabel(lfcmpfalse);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
+      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_TCR0}, NR_R0, 1));
+      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
       cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
 
     end;
@@ -457,11 +528,11 @@ begin
       else
         op := A_C_EQ_S;
       current_asmdata.getjumplabel(lfcmpfalse);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
+      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_TCR0}, NR_R0, NR_R0));
+      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:
@@ -471,11 +542,11 @@ begin
       else
         op := A_C_LT_S;
       current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
+      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_TCR0}, NR_R0, NR_R0));
+      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:
@@ -485,11 +556,11 @@ begin
       else
         op := A_C_LE_S;
       current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
+      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_TCR0}, NR_R0, NR_R0));
+      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:
@@ -499,11 +570,11 @@ begin
       else
         op := A_C_LT_S;
       current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
+      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_TCR0}, NR_R0, NR_R0));
+      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:
@@ -513,11 +584,11 @@ begin
       else
         op := A_C_LE_S;
       current_asmdata.getjumplabel(lfcmptrue);
-      current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
+      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_TCR0}, NR_R0, NR_R0));
+      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;
   end; {case}
@@ -526,11 +597,12 @@ end;
 
 procedure tmipsaddnode.second_cmpboolean;
 var
-  tmp_right_reg: TRegister;
+  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);
@@ -540,18 +612,19 @@ begin
     tmp_right_reg := right.location.Register;
 
   location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
+  location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg);
 end;
 
 
 procedure tmipsaddnode.second_cmpsmallset;
 var
-  tmp_right_reg: TRegister;
+  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
@@ -565,7 +638,7 @@ begin
 
 
   location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
+  location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg);
 end;
 
 
@@ -582,20 +655,21 @@ begin
             not(is_signed(right.resultdef));
 
   location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := GetRes64_register(unsigned, {NR_TCR0, }left.location.register64, right.location.register64); // NR_TCR0;
+  location.Register := GetRes64_register(unsigned, left.location.register64, right.location.register64); 
 end;
 
 
 procedure tmipsaddnode.second_cmpordinal;
 var
   unsigned: boolean;
-  tmp_right_reg: TRegister;
+  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);
@@ -604,7 +678,7 @@ begin
   else
     tmp_right_reg := right.location.Register;
   location_reset(location, LOC_REGISTER, OS_INT);
-  location.Register := getres_register(unsigned, NR_TCR0, left.location.Register, tmp_right_reg);
+  location.Register := getres_register(unsigned, tmpreg, left.location.Register, tmp_right_reg);
 end;
 
 begin
diff --git a/compiler/mips/ncpucnv.pas b/compiler/mips/ncpucnv.pas
index c6361ddb8b..afc69a5872 100644
--- a/compiler/mips/ncpucnv.pas
+++ b/compiler/mips/ncpucnv.pas
@@ -134,6 +134,7 @@ var
   href:      treference;
   hregister: tregister;
   l1, l2:    tasmlabel;
+  ai : TaiCpu;
 
 begin
   location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef));
@@ -149,7 +150,9 @@ begin
 
     loadsigned;
 
-    current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BGE, hregister, NR_R0, l2));
+    ai := Taicpu.op_reg_reg_sym(A_BC, hregister, NR_R0, l2);
+    ai.setCondition(C_GE);
+    current_asmdata.CurrAsmList.concat(ai);
 
     case tfloatdef(resultdef).floattype of
       { converting dword to s64real first and cut off at the end avoids precision loss }
@@ -214,6 +217,8 @@ var
   hreg1, hreg2: tregister;
   opsize: tcgsize;
   hlabel, oldtruelabel, oldfalselabel: tasmlabel;
+  newsize  : tcgsize;
+  href: treference;
 begin
   oldtruelabel  := current_procinfo.CurrTrueLabel;
   oldfalselabel := current_procinfo.CurrFalseLabel;
@@ -223,17 +228,24 @@ begin
   if codegenerror then
     exit;
 
-  { byte(boolean) or word(wordbool) or longint(longbool) must }
-  { be accepted for var parameters                            }
-  if (nf_explicit in flags) and
-    (left.resultdef.size = resultdef.size) and
-    (left.location.loc in [LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER]) then
-  begin
-    location_copy(location, left.location);
-    current_procinfo.CurrTrueLabel  := oldtruelabel;
-    current_procinfo.CurrFalseLabel := oldfalselabel;
-    exit;
-  end;
+         { Explicit typecasts from any ordinal type to a boolean type }
+         { must not change the ordinal value                          }
+         if (nf_explicit in flags) and
+            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
+           begin
+              location_copy(location,left.location);
+              newsize:=def_cgsize(resultdef);
+              { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
+              if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
+                 ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
+                hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true)
+              else
+                location.size:=newsize;
+              current_procinfo.CurrTrueLabel:=oldTrueLabel;
+              current_procinfo.CurrFalseLabel:=oldFalseLabel;
+              exit;
+           end;
+
   location_reset(location, LOC_REGISTER, def_cgsize(resultdef));
   opsize := def_cgsize(left.resultdef);
   case left.location.loc of
@@ -242,21 +254,35 @@ begin
       if left.location.loc in [LOC_CREFERENCE, LOC_REFERENCE] then
       begin
         hreg2 := cg.getintregister(current_asmdata.CurrAsmList, opsize);
-        cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2);
+{$ifndef cpu64bitalu}
+        if left.location.size in [OS_64,OS_S64] then
+          begin
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,left.location.reference,hreg2);
+            hreg1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+            href:=left.location.reference;
+            inc(href.offset,4);
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hreg1);
+            cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,hreg1,hreg2,hreg2);
+          end
+          else
+{$endif not cpu64bitalu}
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2);
       end
       else
-        hreg2 := left.location.Register;
-{$ifndef cpu64bit}
-      if left.location.size in [OS_64, OS_S64] then
-      begin
-        hreg1 := cg.getintregister(current_asmdata.CurrAsmList, OS_32);
-        cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hreg2, tregister(succ(longint(hreg2))), hreg1);
-        hreg2  := hreg1;
-        opsize := OS_32;
-      end;
-{$endif cpu64bit}
-      hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize);
-        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0));
+        begin
+          hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+{$ifndef cpu64bitalu}
+          if left.location.size in [OS_64,OS_S64] then
+            begin
+              hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,left.location.register64.reglo,hreg2);
+             end
+           else
+{$endif not cpu64bitalu}
+             cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,left.location.register,hreg2);
+         end;
+       hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize);
+       current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0));
     end;
     LOC_JUMP:
     begin
@@ -272,10 +298,26 @@ begin
     else
       internalerror(10062);
   end;
-  location.Register := hreg1;
+{$ifndef cpu64bitalu}
+  if (location.size in [OS_64,OS_S64]) then
+    begin
+      location.register64.reglo:=hreg1;
+      location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+      if (is_cbool(resultdef)) then
+       { reglo is either 0 or -1 -> reghi has to become the same }
+      	cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi)
+       else
+       { unsigned }
+         cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi);
+       end
+       else
+{$endif not cpu64bitalu}
+         location.Register := hreg1;
 
+{zfx
   if location.size in [OS_64, OS_S64] then
     internalerror(200408241);
+}
 
   current_procinfo.CurrTrueLabel  := oldtruelabel;
   current_procinfo.CurrFalseLabel := oldfalselabel;
diff --git a/compiler/mips/ncpumat.pas b/compiler/mips/ncpumat.pas
index bf894d8a64..2c93a71e56 100644
--- a/compiler/mips/ncpumat.pas
+++ b/compiler/mips/ncpumat.pas
@@ -257,6 +257,7 @@ end;
 procedure tMIPSELnotnode.second_boolean;
 var
   hl: tasmlabel;
+  tmpreg : TRegister;
 begin
   { if the location is LOC_JUMP, we do the secondpass after the
           labels are allocated
@@ -283,10 +284,11 @@ begin
       end;
       LOC_REGISTER, LOC_CREGISTER, LOC_REFERENCE, LOC_CREFERENCE:
       begin
+        tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
         hlcg.location_force_reg(current_asmdata.CurrAsmList, left.location, left.resultdef, left.resultdef, True);
-        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SEQ, NR_TCR0, left.location.Register, NR_R0));
+        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SEQ, tmpreg, left.location.Register, NR_R0));
         location_reset(location, LOC_REGISTER, OS_INT);
-        location.Register := NR_TCR0;
+        location.Register := tmpreg;
       end;
       else
         internalerror(2003042401);
diff --git a/compiler/mips/opcode.inc b/compiler/mips/opcode.inc
index 9e9e292fa7..1f15252bbb 100644
--- a/compiler/mips/opcode.inc
+++ b/compiler/mips/opcode.inc
@@ -1,5 +1,4 @@
 A_NONE,
-A_P_STK2,
 A_P_LW,
 A_P_SET_NOMIPS16,
 A_P_SET_NOREORDER,
@@ -15,7 +14,8 @@ A_NOP,
 A_NOT,
 A_NEG,
 A_NEGU,
-A_B,
+A_BA,
+A_BC,
 A_LI,
 A_DLI,
 A_LA,
@@ -108,22 +108,6 @@ A_J,
 A_JAL,
 A_JR,
 A_JALR,
-A_BEQ,
-A_BNE,
-A_BLEZ,
-A_BGTZ,
-A_BLTZ,
-A_BGEZ,
-A_BLTZAL,
-A_BGEZAL,
-A_BEQL,
-A_BNEL,
-A_BLEZL,
-A_BGTZL,
-A_BLTZL,
-A_BGEZL,
-A_BLTZALL,
-A_BGEZALL,
 A_SLL,
 A_SRL,
 A_SRA,
@@ -193,32 +177,12 @@ A_FLOOR_L_S,
 A_FLOOR_L_D,
 A_BC1T,
 A_BC1F,
-A_BC1TL,
-A_BC1FL,
 A_C_EQ_D,
 A_C_EQ_S,
 A_C_LE_D,
 A_C_LE_S,
 A_C_LT_D,
 A_C_LT_S,
-A_BEQI,
-A_BNEI,
-A_BLTI,
-A_BLEI,
-A_BGTI,
-A_BGEI,
-A_BLTUI,
-A_BLEUI,
-A_BGTUI,
-A_BGEUI,
-A_BLT,
-A_BLE,
-A_BGT,
-A_BGE,
-A_BLTU,
-A_BLEU,
-A_BGTU,
-A_BGEU,
 A_SEQ,
 A_SGE,
 A_SGEU,
diff --git a/compiler/mips/racpugas.pas b/compiler/mips/racpugas.pas
index d1b06b3406..b94eb2b0fe 100644
--- a/compiler/mips/racpugas.pas
+++ b/compiler/mips/racpugas.pas
@@ -639,7 +639,7 @@ Interface
           begin
             { we can search here without an extra table which is sorted by string length
               because we take the whole remaining string without the leading B }
-            actopcode := A_B;
+            actopcode := A_BC;
             for cond:=low(TAsmCond) to high(TAsmCond) do
               if (Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
                 begin
diff --git a/compiler/mips/strinst.inc b/compiler/mips/strinst.inc
index eee1e43386..ccab5b5e0c 100644
--- a/compiler/mips/strinst.inc
+++ b/compiler/mips/strinst.inc
@@ -1,5 +1,4 @@
 'none',
-'p_stk2',
 'p_lw',
 'p_set_nomips16',
 'p_set_noreorder',
@@ -15,6 +14,7 @@
 'not',
 'neg',
 'negu',
+'b ',
 'b',
 'li',
 'dli',
@@ -108,22 +108,6 @@
 'jal',
 'jr',
 'jalr',
-'beq',
-'bne',
-'blez',
-'bgtz',
-'bltz',
-'bgez',
-'bltzal',
-'bgezal',
-'beql',
-'bnel',
-'blezl',
-'bgtzl',
-'bltzl',
-'bgezl',
-'bltzall',
-'bgezall',
 'sll',
 'srl',
 'sra',
@@ -193,32 +177,12 @@
 'floor.l.d',
 'bc1t',
 'bc1f',
-'bc1tl',
-'bc1fl',
 'c.eq.d',
 'c.eq.s',
 'c.le.d',
 'c.le.s',
 'c.lt.d',
 'c.lt.s',
-'beqi',
-'bnei',
-'blti',
-'blei',
-'bgti',
-'bgei',
-'bltui',
-'bleui',
-'bgtui',
-'bgeui',
-'blt',
-'ble',
-'bgt',
-'bge',
-'bltu',
-'bleu',
-'bgtu',
-'bgeu',
 'seq',
 'sge',
 'sgeu',