소스 검색

* more MIPS code of David Zhang integrated

git-svn-id: trunk@14228 -
florian 15 년 전
부모
커밋
0c8546f94c

+ 10 - 4
.gitattributes

@@ -234,15 +234,21 @@ compiler/m68k/ra68k.pas svneol=native#text/plain
 compiler/m68k/ra68kmot.pas svneol=native#text/plain
 compiler/m68k/rgcpu.pas svneol=native#text/plain
 compiler/mips/aasmcpu.pas svneol=native#text/plain
-compiler/mips/cgcpu.pas svneol=native#text/pascal
+compiler/mips/aoptcpu.pas svneol=native#text/plain
+compiler/mips/aoptcpub.pas svneol=native#text/plain
+compiler/mips/aoptcpud.pas svneol=native#text/plain
+compiler/mips/cgcpu.pas svneol=native#text/plain
 compiler/mips/cpubase.pas svneol=native#text/plain
+compiler/mips/cpugas.pas svneol=native#text/plain
 compiler/mips/cpuinfo.pas svneol=native#text/plain
-compiler/mips/cpupara.pas svneol=native#text/pascal
-compiler/mips/cpupi.pas svneol=native#text/pascal
+compiler/mips/cpunode.pas svneol=native#text/plain
+compiler/mips/cpupara.pas svneol=native#text/plain
+compiler/mips/cpupi.pas svneol=native#text/plain
 compiler/mips/itcpugas.pas svneol=native#text/plain
 compiler/mips/mipsreg.dat svneol=native#text/plain
+compiler/mips/ncpuadd.pas svneol=native#text/plain
 compiler/mips/opcode.inc svneol=native#text/plain
-compiler/mips/rgcpu.pas svneol=native#text/pascal
+compiler/mips/rgcpu.pas svneol=native#text/plain
 compiler/mips/rmipscon.inc svneol=native#text/plain
 compiler/mips/rmipsdwf.inc svneol=native#text/plain
 compiler/mips/rmipsgas.inc svneol=native#text/plain

+ 2 - 2
compiler/arm/cgcpu.pas

@@ -3067,7 +3067,7 @@ unit cgcpu;
               begin
                 { restore int registers and return }
                 list.concat(taicpu.op_reg_reg(A_MOV, NR_STACK_POINTER_REG, NR_R11));
-                
+
                 reference_reset(ref,4);
                 ref.index:=NR_STACK_POINTER_REG;
                 list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,regs),PF_DB));
@@ -3195,7 +3195,7 @@ unit cgcpu;
             tmpreg:=getintregister(list,OS_ADDR);
 
             list.concat(taicpu.op_reg_reg(A_MOV, tmpreg, NR_R15));
-        
+
             ref.base := tmpreg;
           end;
 

+ 370 - 260
compiler/mips/aasmcpu.pas

@@ -1,7 +1,7 @@
 {
-    Copyright (c) 2003 by Florian Klaempfl
+    Copyright (c) 1999-2009 by Mazen Neifer and David Zhang
 
-    Contains the assembler object for MIPS
+    Contains the assembler object for the MIPSEL
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -26,314 +26,424 @@ unit aasmcpu;
 interface
 
 uses
-  cclasses,aasmtai,aasmdata,
-  aasmbase,globtype,globals,verbose,
-  cpubase,cpuinfo,cgbase,cgutils;
+  cclasses,
+  globtype, globals, verbose,
+  aasmbase, aasmtai,
+  cgbase, cgutils, cpubase, cpuinfo;
 
-    const
-      { "mov reg,reg" source operand number }
-      O_MOV_SOURCE = 1;
-      { "mov reg,reg" source operand number }
-      O_MOV_DEST = 0;
+const
+  { "mov reg,reg" source operand number }
+  O_MOV_SOURCE = 0;
+  { "mov reg,reg" source operand number }
+  O_MOV_DEST   = 1;
 
-    type
-      taicpu = class(tai_cpu_abstract)
-         constructor op_none(op : tasmop);
+type
+  taicpu = class(tai_cpu_abstract)
+    delayslot_annulled: boolean;   { conditinal opcode with ,a }
+    constructor op_none(op: tasmop);
 
-         constructor op_reg(op : tasmop;_op1 : tregister);
-         constructor op_const(op : tasmop;_op1 : longint);
+    constructor op_reg(op: tasmop; _op1: tregister);
+    constructor op_const(op: tasmop; _op1: longint);
+    constructor op_ref(op: tasmop; const _op1: treference);
 
-         constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
-         constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
-         constructor op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
+    constructor op_reg_reg(op: tasmop; _op1, _op2: tregister);
+    constructor op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference);
+    constructor op_reg_const(op: tasmop; _op1: tregister; _op2: longint);
 
-         constructor op_ref_regset(op:tasmop; _op1: treference; _op2: tcpuregisterset);
+    constructor op_reg_reg_reg(op: tasmop; _op1, _op2, _op3: tregister);
 
-         constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
-         constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
-         constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
-         constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
-         { SFM/LFM }
-         constructor op_reg_const_ref(op : tasmop;_op1 : tregister;_op2 : aint;_op3 : treference);
+    constructor op_reg_reg_ref(op: tasmop; _op1, _op2: tregister; const _op3: treference);
+    constructor op_reg_reg_const(op: tasmop; _op1, _op2: tregister; _op3: aint);
 
-         { this is for Jmp instructions }
-         constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
+    { this is for Jmp instructions }
+    constructor op_sym(op: tasmop; _op1: tasmsymbol);
+    constructor op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
+    constructor op_reg_sym(op: tasmop; _op1: tregister; _op2: tasmsymbol);
+    constructor op_sym_ofs(op: tasmop; _op1: tasmsymbol; _op1ofs: longint);
 
-         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
-         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
-         constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
-         constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
+    { register allocation }
+    function is_same_reg_move(regtype: Tregistertype): boolean; override;
 
-         function is_same_reg_move(regtype: Tregistertype):boolean; override;
+    { register spilling code }
+    function spilling_get_operation_type(opnr: longint): topertype; override;
+  end;
 
-         function spilling_get_operation_type(opnr: longint): topertype;override;
-      end;
-      tai_align = class(tai_align_abstract)
-        { nothing to add }
-      end;
-
-    function spilling_create_load(const ref:treference;r:tregister): tai;
-    function spilling_create_store(r:tregister; const ref:treference): tai;
+  tai_align = class(tai_align_abstract)
+    { nothing to add }
+  end;
 
-    procedure InitAsm;
-    procedure DoneAsm;
+  procedure InitAsm;
+  procedure DoneAsm;
 
+  function spilling_create_load(const ref: treference; r: tregister): taicpu;
+  function spilling_create_store(r: tregister; const ref: treference): taicpu;
 
 implementation
 
-  uses
-    cutils,rgobj,itcpugas;
-
-
 {*****************************************************************************
                                  taicpu Constructors
 *****************************************************************************}
 
-    constructor taicpu.op_none(op : tasmop);
-      begin
-         inherited create(op);
-      end;
 
 
-    constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
-      begin
-         inherited create(op);
-         ops:=1;
-         loadreg(0,_op1);
-      end;
+constructor taicpu.op_none(op: tasmop);
+begin
+  inherited Create(op);
+end;
+
+
+constructor taicpu.op_reg(op: tasmop; _op1: tregister);
+begin
+  inherited Create(op);
+  ops := 1;
+  loadreg(0, _op1);
+end;
+
+
+constructor taicpu.op_ref(op: tasmop; const _op1: treference);
+begin
+  inherited Create(op);
+  ops := 1;
+  loadref(0, _op1);
+end;
+
+
+constructor taicpu.op_const(op: tasmop; _op1: longint);
+begin
+  inherited Create(op);
+  ops := 1;
+  loadconst(0, _op1);
+end;
+
+
+constructor taicpu.op_reg_reg(op: tasmop; _op1, _op2: tregister);
+begin
+  inherited Create(op);
+  ops := 2;
+  loadreg(0, _op1);
+  loadreg(1, _op2);
+end;
+
+constructor taicpu.op_reg_const(op: tasmop; _op1: tregister; _op2: longint);
+begin
+  inherited Create(op);
+  ops := 2;
+  loadreg(0, _op1);
+  loadconst(1, _op2);
+end;
+
+
+constructor taicpu.op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference);
+begin
+  inherited Create(op);
+  ops := 2;
+  loadreg(0, _op1);
+  loadref(1, _op2);
+end;
+
+
+constructor taicpu.op_reg_reg_reg(op: tasmop; _op1, _op2, _op3: tregister);
+begin
+  inherited Create(op);
+  ops := 3;
+  loadreg(0, _op1);
+  loadreg(1, _op2);
+  loadreg(2, _op3);
+end;
+
+
+constructor taicpu.op_reg_reg_ref(op: tasmop; _op1, _op2: tregister; const _op3: treference);
+ begin
+   inherited create(op);
+   ops := 3;
+   loadreg(0, _op1);
+   loadreg(1, _op2);
+   loadref(2, _op3);
+end;
+
+constructor taicpu.op_reg_reg_const(op: tasmop; _op1, _op2: tregister; _op3: aint);
+ begin
+   inherited create(op);
+   ops := 3;
+   loadreg(0, _op1);
+   loadreg(1, _op2);
+   loadconst(2, _op3);
+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
+    ];
+
+  ops := 1;
+  loadsymbol(0, _op1, 0);
+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];
+   ops := 3;
+   loadreg(0, _op1);
+   loadreg(1, _op2);
+   loadsymbol(2, _op3, 0);
+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];
+   ops := 2;
+   loadreg(0, _op1);
+   loadsymbol(1, _op2, 0);
+end;
+
+constructor taicpu.op_sym_ofs(op: tasmop; _op1: tasmsymbol; _op1ofs: longint);
+begin
+  inherited Create(op);
+  ops := 1;
+  loadsymbol(0, _op1, _op1ofs);
+end;
+
+
+function taicpu.is_same_reg_move(regtype: Tregistertype): boolean;
+begin
+  Result := (
+    ((opcode = A_MOVE) and (regtype = R_INTREGISTER)) or
+    ((regtype = R_FPUREGISTER) and (opcode in [A_MOV_S, A_MOV_D]))
+    ) and
+    (oper[0]^.reg = oper[1]^.reg);
+end;
 
 
-    constructor taicpu.op_const(op : tasmop;_op1 : longint);
-      begin
-         inherited create(op);
-         ops:=1;
-         loadconst(0,aint(_op1));
-      end;
-
-
-    constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
-      begin
-         inherited create(op);
-         ops:=2;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-      end;
-
-
-    constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
-      begin
-         inherited create(op);
-         ops:=2;
-         loadreg(0,_op1);
-         loadconst(1,aint(_op2));
-      end;
-
-
-    constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
-      begin
-         inherited create(op);
-         ops:=2;
-         loadreg(0,_op1);
-         loadref(1,_op2);
-      end;
-
-
-    constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
-      begin
-         inherited create(op);
-         ops:=3;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-         loadreg(2,_op3);
-      end;
-
-
-     constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
-       begin
-         inherited create(op);
-         ops:=3;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-         loadconst(2,aint(_op3));
-      end;
-
-
-    constructor taicpu.op_reg_const_ref(op : tasmop;_op1 : tregister;_op2 : aint;_op3 : treference);
-      begin
-         inherited create(op);
-         ops:=3;
-         loadreg(0,_op1);
-         loadconst(1,_op2);
-         loadref(2,_op3);
-      end;
-
-
-     constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
-       begin
-         inherited create(op);
-         ops:=3;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-         loadsymbol(0,_op3,_op3ofs);
-      end;
-
-
-     constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
-       begin
-         inherited create(op);
-         ops:=3;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-         loadref(2,_op3);
-      end;
-
-
-    constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
-      begin
-         inherited create(op);
-         condition:=cond;
-         ops:=1;
-         loadsymbol(0,_op1,0);
-      end;
-
-
-    constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
-      begin
-         inherited create(op);
-         ops:=1;
-         loadsymbol(0,_op1,0);
-      end;
-
-
-    constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
-      begin
-         inherited create(op);
-         ops:=1;
-         loadsymbol(0,_op1,_op1ofs);
-      end;
-
-
-     constructor taicpu.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
-      begin
-         inherited create(op);
-         ops:=2;
-         loadreg(0,_op1);
-         loadsymbol(1,_op2,_op2ofs);
-      end;
-
-
-    constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
-      begin
-         inherited create(op);
-         ops:=2;
-         loadsymbol(0,_op1,_op1ofs);
-         loadref(1,_op2);
-      end;
-
-
-{ ****************************** newra stuff *************************** }
+    function taicpu.spilling_get_operation_type(opnr: longint): topertype;
+      type
+        op_write_set_type =  set of TAsmOp;
+      const
+        op_write_set: op_write_set_type =
+      [A_NEG,
+      A_NEGU,
+      A_LI,
+      A_DLI,
+      A_LA,
+      A_MOVE,
+      A_LB,
+      A_LBU,
+      A_LH,
+      A_LHU,
+      A_LW,
+      A_LWU,
+      A_LWL,
+      A_LWR,
+      A_LD,
+      A_LDL,
+      A_LDR,
+      A_LL,
+      A_LLD,
+      A_ADDI,
+      A_DADDI,
+      A_ADDIU,
+      A_DADDIU,
+      A_SLTI,
+      A_SLTIU,
+      A_ANDI,
+      A_ORI,
+      A_XORI,
+      A_LUI,
+      A_DNEG,
+      A_DNEGU,
+      A_ADD,
+      A_DADD,
+      A_ADDU,
+      A_DADDU,
+      A_SUB,
+      A_DSUB,
+      A_SUBU,
+      A_DSUBU,
+      A_SLT,
+      A_SLTU,
+      A_AND,
+      A_OR,
+      A_XOR,
+      A_NOR,
+      A_MUL,
+      A_MULO,
+      A_MULOU,
+      A_DMUL,
+      A_DMULO,
+      A_DMULOU,
+      A_DIV,
+      A_DIVU,
+      A_DDIV,
+      A_DDIVU,
+      A_REM,
+      A_REMU,
+      A_DREM,
+      A_DREMU,
+      A_MULT,
+      A_DMULT,
+      A_MULTU,
+      A_DMULTU,
+      A_MFHI,
+      A_MFLO,
+      A_MULTG,
+      A_DMULTG,
+      A_MULTUG,
+      A_DMULTUG,
+      A_DIVG,
+      A_DDIVG,
+      A_DIVUG,
+      A_DDIVUG,
+      A_MODG,
+      A_DMODG,
+      A_MODUG,
+      A_DMODUG,
+
+      A_SLL,
+      A_SRL,
+      A_SRA,
+      A_SLLV,
+      A_SRLV,
+      A_SRAV,
+      A_DSLL,
+      A_DSRL,
+      A_DSRA,
+      A_DSLLV,
+      A_DSRLV,
+      A_DSRAV,
+      A_DSLL32,
+      A_DSRL32,
+      A_DSRA32,
+      A_LWC1,
+      A_LDC1,
+
+
+      A_ADD_S,
+      A_ADD_D,
+      A_SUB_S,
+      A_SUB_D,
+      A_MUL_S,
+      A_MUL_D,
+      A_DIV_S,
+      A_DIV_D,
+      A_ABS_S,
+      A_ABS_D,
+      A_NEG_S,
+      A_NEG_D,
+      A_SQRT_S,
+      A_SQRT_D,
+      A_MOV_S,
+      A_MOV_D,
+      A_CVT_S_D,
+      A_CVT_S_W,
+      A_CVT_S_L,
+      A_CVT_D_S,
+      A_CVT_D_W,
+      A_CVT_D_L,
+      A_CVT_W_S,
+      A_CVT_W_D,
+      A_CVT_L_S,
+      A_CVT_L_D,
+      A_ROUND_W_S,
+      A_ROUND_W_D,
+      A_ROUND_L_S,
+      A_ROUND_L_D,
+      A_TRUNC_W_S,
+      A_TRUNC_W_D,
+      A_TRUNC_L_S,
+      A_TRUNC_L_D,
+      A_CEIL_W_S,
+      A_CEIL_W_D,
+      A_CEIL_L_S,
+      A_CEIL_L_D,
+      A_FLOOR_W_S,
+      A_FLOOR_W_D,
+      A_FLOOR_L_S,
+      A_FLOOR_L_D,
+      A_SEQ,
+      A_SGE,
+      A_SGEU,
+      A_SGT,
+      A_SGTU,
+      A_SLE,
+      A_SLEU,
+      A_SNE];
 
-    function taicpu.is_same_reg_move(regtype: Tregistertype):boolean;
       begin
-        { allow the register allocator to remove unnecessary moves }
-        result:=(((opcode=A_MOVE) and (regtype = R_INTREGISTER)) or
-                 ((opcode=A_MOVF) and (regtype = R_FPUREGISTER))
-                ) and
-                (condition=C_None) and
-                (ops=2) and
-                (oper[0]^.typ=top_reg) and
-                (oper[1]^.typ=top_reg) and
-                (oper[0]^.reg=oper[1]^.reg);
+        result := operand_read;
+        if opcode in op_write_set then
+          if opnr = 0 then
+            result := operand_write;
       end;
 
 
-    function spilling_create_load(const ref:treference;r:tregister): tai;
+    function spilling_create_load(const ref: treference; r: tregister): taicpu;
       begin
         case getregtype(r) of
           R_INTREGISTER :
-            result:=taicpu.op_reg_ref(A_LDR,r,ref);
+            result:=taicpu.op_reg_ref(A_LW,r,ref);
           R_FPUREGISTER :
-            { use lfm because we don't know the current internal format
-              and avoid exceptions
-            }
-            result:=taicpu.op_reg_const_ref(A_LFM,r,1,ref);
+            begin
+              case getsubreg(r) of
+                R_SUBFS :
+                  result:=taicpu.op_reg_ref(A_LWC1,r,ref);
+                R_SUBFD :
+                  result:=taicpu.op_reg_ref(A_LDC1,r,ref);
+                else
+                  internalerror(200401042);
+              end;
+            end
           else
             internalerror(200401041);
         end;
       end;
 
 
-    function spilling_create_store(r:tregister; const ref:treference): tai;
+    function spilling_create_store(r: tregister; const ref: treference): taicpu;
       begin
         case getregtype(r) of
           R_INTREGISTER :
-            result:=taicpu.op_reg_ref(A_STR,r,ref);
+            result:=taicpu.op_reg_ref(A_SW,r,ref);
           R_FPUREGISTER :
-            { use sfm because we don't know the current internal format
-              and avoid exceptions
-            }
-            result:=taicpu.op_reg_const_ref(A_SFM,r,1,ref);
+            begin
+              case getsubreg(r) of
+                R_SUBFS :
+                  result:=taicpu.op_reg_ref(A_SWC1,r,ref);
+                R_SUBFD :
+                  result:=taicpu.op_reg_ref(A_SDC1,r,ref);
+                else
+                  internalerror(200401042);
+              end;
+            end
           else
             internalerror(200401041);
         end;
       end;
 
 
-    function taicpu.spilling_get_operation_type(opnr: longint): topertype;
-      begin
-        case opcode of
-          A_ADC,A_ADD,A_AND,
-          A_EOR,A_CLZ,
-          A_LDR,A_LDRB,A_LDRD,A_LDRBT,A_LDRH,A_LDRSB,
-          A_LDRSH,A_LDRT,
-          A_MOV,A_MVN,A_MLA,A_MUL,
-          A_ORR,A_RSB,A_RSC,A_SBC,A_SUB,
-          A_SWP,A_SWPB,
-          A_LDF,A_FLT,A_FIX,
-          A_ADF,A_DVF,A_FDV,A_FML,
-          A_RFS,A_RFC,A_RDF,
-          A_RMF,A_RPW,A_RSF,A_SUF,A_ABS,A_ACS,A_ASN,A_ATN,A_COS,
-          A_EXP,A_LOG,A_LGN,A_MVF,A_MNF,A_FRD,A_MUF,A_POL,A_RND,A_SIN,A_SQT,A_TAN,
-          A_LFM:
-            if opnr=0 then
-              result:=operand_write
-            else
-              result:=operand_read;
-          A_BIC,A_BKPT,A_B,A_BL,A_BLX,A_BX,
-          A_CMN,A_CMP,A_TEQ,A_TST,
-          A_CMF,A_CMFE,A_WFS,A_CNF:
-            result:=operand_read;
-          A_SMLAL,A_UMLAL:
-            if opnr in [0,1] then
-              result:=operand_readwrite
-            else
-              result:=operand_read;
-           A_SMULL,A_UMULL:
-            if opnr in [0,1] then
-              result:=operand_write
-            else
-              result:=operand_read;
-          A_STR,A_STRB,A_STRBT,A_STRD,
-          A_STRH,A_STRT,A_STF,A_SFM:
-            { important is what happens with the involved registers }
-            if opnr=0 then
-              result := operand_read
-            else
-              { check for pre/post indexed }
-              result := operand_read;
-          else
-            internalerror(200403151);
-        end;
-      end;
-
+procedure InitAsm;
+  begin
+  end;
 
-    procedure InitAsm;
-      begin
-      end;
 
+procedure DoneAsm;
+  begin
+  end;
 
-    procedure DoneAsm;
-      begin
-      end;
 
+begin
+  cai_cpu   := taicpu;
+  cai_align := tai_align;
 end.

+ 41 - 0
compiler/mips/aoptcpu.pas

@@ -0,0 +1,41 @@
+{
+    Copyright (c) 1998-2004 by Jonas Maebe
+
+    This unit calls the optimization procedures to optimize the assembler
+    code for sparc
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+
+unit aoptcpu;
+
+{$i fpcdefs.inc}
+
+  Interface
+
+    uses
+      cpubase, aoptobj, aoptcpub, aopt;
+
+    Type
+      TCpuAsmOptimizer = class(TAsmOptimizer)
+      End;
+
+  Implementation
+
+begin
+  casmoptimizer:=TCpuAsmOptimizer;
+end.

+ 119 - 0
compiler/mips/aoptcpub.pas

@@ -0,0 +1,119 @@
+ {
+    Copyright (c) 1998-2009 by Jonas Maebe and David Zhang
+
+    This unit contains several types and constants necessary for the
+    optimizer to work on the MIPSEL architecture
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+Unit aoptcpub; { Assembler OPTimizer CPU specific Base }
+
+{$i fpcdefs.inc}
+
+{ enable the following define if memory references can have both a base and }
+{ index register in 1 operand                                               }
+
+{$define RefsHaveIndexReg}
+
+{ enable the following define if memory references can have a scaled index }
+
+{ define RefsHaveScale}
+
+{ enable the following define if memory references can have a segment }
+{ override                                                            }
+
+{ define RefsHaveSegment}
+
+Interface
+
+Uses
+  cpubase,aasmcpu,AOptBase;
+
+Type
+
+{ type of a normal instruction }
+  TInstr = Taicpu;
+  PInstr = ^TInstr;
+
+{ ************************************************************************* }
+{ **************************** TCondRegs ********************************** }
+{ ************************************************************************* }
+{ Info about the conditional registers                                      }
+  TCondRegs = Object
+    Constructor Init;
+    Destructor Done;
+  End;
+
+{ ************************************************************************* }
+{ **************************** TAoptBaseCpu ******************************* }
+{ ************************************************************************* }
+
+  TAoptBaseCpu = class(TAoptBase)
+  End;
+
+
+{ ************************************************************************* }
+{ ******************************* Constants ******************************* }
+{ ************************************************************************* }
+Const
+
+{ the maximum number of things (registers, memory, ...) a single instruction }
+{ changes                                                                    }
+
+  MaxCh = 3;
+
+{ the maximum number of operands an instruction has }
+
+  MaxOps = 3;
+
+{Oper index of operand that contains the source (reference) with a load }
+{instruction                                                            }
+
+  LoadSrc = 0;
+
+{Oper index of operand that contains the destination (register) with a load }
+{instruction                                                                }
+
+  LoadDst = 1;
+
+{Oper index of operand that contains the source (register) with a store }
+{instruction                                                            }
+
+  StoreSrc = 0;
+
+{Oper index of operand that contains the destination (reference) with a load }
+{instruction                                                                 }
+
+  StoreDst = 1;
+
+  aopt_uncondjmp = A_J;
+  aopt_condjmp = A_BEQ;
+
+Implementation
+
+{ ************************************************************************* }
+{ **************************** TCondRegs ********************************** }
+{ ************************************************************************* }
+Constructor TCondRegs.init;
+Begin
+End;
+
+Destructor TCondRegs.Done; {$ifdef inl} inline; {$endif inl}
+Begin
+End;
+
+End.

+ 36 - 0
compiler/mips/aoptcpud.pas

@@ -0,0 +1,36 @@
+{
+    Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
+    Development Team
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+Unit aoptcpud;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      aoptda;
+
+    type
+      TAOptDFACpu = class(TAOptDFA)
+      end;
+
+  implementation
+
+end.

+ 94 - 101
compiler/mips/cgcpu.pas

@@ -101,7 +101,7 @@ type
     procedure a_op64_reg_reg_reg_checkoverflow(list: tasmlist; op: TOpCG; size: tcgsize; regsrc1, regsrc2, regdst: tregister64; setflags: boolean; var ovloc: tlocation); override;
   end;
 
-
+  procedure create_codegen;
 
 implementation
 
@@ -336,20 +336,20 @@ begin
     (ref.offset > simm16hi) then
   begin
     tmpreg := GetIntRegister(list, OS_INT);
-    reference_reset(tmpref);
+    reference_reset(tmpref,sizeof(aint));
     tmpref.symbol  := ref.symbol;
     tmpref.offset  := ref.offset;
-    tmpref.refaddr := addr_hi;
+    tmpref.refaddr := addr_high;
     list.concat(taicpu.op_reg_ref(A_LUI, tmpreg, tmpref));
     if (ref.offset = 0) and (ref.index = NR_NO) and
       (ref.base = NR_NO) then
     begin
-      ref.refaddr := addr_lo;
+      ref.refaddr := addr_low;
     end
     else
     begin
       { Load the low part is left }
-      tmpref.refaddr := addr_lo;
+      tmpref.refaddr := addr_low;
       list.concat(taicpu.op_reg_reg_ref(A_ADDIU, tmpreg, tmpreg, tmpref));
       ref.offset := 0;
       { symbol is loaded }
@@ -405,7 +405,7 @@ begin
     assigned(ref.symbol) then
   begin
     tmpreg := GetIntRegister(list, OS_INT);
-    reference_reset(tmpref);
+    reference_reset(tmpref,sizeof(aint));
     tmpref.symbol  := ref.symbol;
     tmpref.refaddr := addr_pic;
     if not (pi_needs_got in current_procinfo.flags) then
@@ -435,14 +435,14 @@ begin
   tmpreg1 := GetIntRegister(list, OS_INT);
   if assigned(ref.symbol) then
   begin
-    reference_reset(tmpref);
+    reference_reset(tmpref,sizeof(aint));
     tmpref.symbol  := ref.symbol;
     tmpref.offset  := ref.offset;
-    tmpref.refaddr := addr_hi;
+    tmpref.refaddr := addr_high;
     list.concat(taicpu.op_reg_ref(A_LUI, tmpreg1, tmpref));
     { Load the low part }
 
-    tmpref.refaddr := addr_lo;
+    tmpref.refaddr := addr_low;
     list.concat(taicpu.op_reg_reg_ref(A_ADDIU, tmpreg1, tmpreg1, tmpref));
     { symbol is loaded }
     ref.symbol := nil;
@@ -554,7 +554,7 @@ begin
       begin
         if (Index = NR_SP) and (Offset < Target_info.first_parm_offset) then
           InternalError(2002081104);
-        reference_reset_base(ref, index, offset);
+        reference_reset_base(ref, index, offset, sizeof(aint));
       end;
       a_load_const_ref(list, size, a, ref);
     end;
@@ -581,7 +581,7 @@ begin
         begin
           if (Index = NR_SP) and (Offset < Target_info.first_parm_offset) then
             InternalError(2002081104);
-          reference_reset_base(ref, index, offset);
+          reference_reset_base(ref, index, offset, sizeof(aint));
         end;
         tmpreg := GetIntRegister(list, OS_INT);
         a_load_ref_reg(list, sz, sz, r, tmpreg);
@@ -607,7 +607,7 @@ begin
         a_loadaddr_ref_reg(list, r, Register);
       LOC_REFERENCE:
       begin
-        reference_reset(ref);
+        reference_reset(ref,sizeof(aint));
         ref.base   := reference.index;
         ref.offset := reference.offset;
         tmpreg     := GetAddressRegister(list);
@@ -635,7 +635,7 @@ begin
         a_load_ref_reg(list, hloc^.size, hloc^.size, href, hloc^.Register);
       LOC_REFERENCE:
       begin
-        reference_reset_base(href2, hloc^.reference.index, hloc^.reference.offset);
+        reference_reset_base(href2, hloc^.reference.index, hloc^.reference.offset, sizeof(aint));
         a_load_ref_ref(list, hloc^.size, hloc^.size, href, href2);
       end;
       else
@@ -651,16 +651,16 @@ procedure TCgMPSel.a_paramfpu_reg(list: tasmlist; size: tcgsize; const r: tregis
 var
   href: treference;
 begin
-  tg.GetTemp(list, TCGSize2Size[size], tt_normal, href);
-  a_loadfpu_reg_ref(list, size, r, href);
+  tg.GetTemp(list, TCGSize2Size[size], sizeof(aint), tt_normal, href);
+  a_loadfpu_reg_ref(list, size, size, r, href);
   a_paramfpu_ref(list, size, href, paraloc);
   tg.Ungettemp(list, href);
 end;
 
 
-procedure TCgMPSel.a_call_name(list: tasmlist; const s: string);
+procedure TCgMPSel.a_call_name(list: tasmlist; const s: string; weak: boolean);
 begin
-  list.concat(taicpu.op_sym(A_JAL, objectlibrary.newasmsymbol(s, AB_EXTERNAL, AT_FUNCTION)));
+  list.concat(taicpu.op_sym(A_JAL,current_asmdata.RefAsmSymbol(s)));
   { Delay slot }
   list.concat(taicpu.op_none(A_NOP));
 end;
@@ -827,7 +827,7 @@ begin
   begin
     tmpreg := r; //GetIntRegister(list, OS_ADDR);
     r_used := true;
-    reference_reset(tmpref);
+    reference_reset(tmpref,sizeof(aint));
     tmpref.symbol  := href.symbol;
     tmpref.refaddr := addr_pic;
     if not (pi_needs_got in current_procinfo.flags) then
@@ -858,13 +858,13 @@ begin
       hreg := r
     else
       hreg := GetAddressRegister(list);
-    reference_reset(tmpref);
+    reference_reset(tmpref,sizeof(aint));
     tmpref.symbol  := href.symbol;
     tmpref.offset  := href.offset;
-    tmpref.refaddr := addr_hi;
+    tmpref.refaddr := addr_high;
     list.concat(taicpu.op_reg_ref(A_LUI, hreg, tmpref));
     { Only the low part is left }
-    tmpref.refaddr := addr_lo;
+    tmpref.refaddr := addr_low;
     list.concat(taicpu.op_reg_reg_ref(A_ADDIU, hreg, hreg, tmpref));
     if href.base <> NR_NO then
     begin
@@ -880,8 +880,7 @@ begin
   else
   { At least small offset, maybe base and maybe index }
   if  (href.offset >= simm16lo) and
-    (href.offset <= simm16hi)
-  then
+    (href.offset <= simm16hi) then
   begin
     if href.index <> NR_NO then   { Both base and index }
     begin
@@ -903,8 +902,8 @@ begin
     begin
       list.concat(taicpu.op_reg_reg_const(A_ADDIU, r, href.base, href.offset));
     end
-    else { only offset, can be generated by absolute }
-
+    else
+      { only offset, can be generated by absolute }
       a_load_const_reg(list, OS_ADDR, href.offset, r);
   end
   else
@@ -920,10 +919,10 @@ var
 begin
   if reg1 <> reg2 then
   begin
-    instr := taicpu.op_reg_reg(fpumovinstr[size], reg2, reg1);
+    instr := taicpu.op_reg_reg(fpumovinstr[tosize], reg2, reg1);
     list.Concat(instr);
-            { Notify the register allocator that we have written a move instruction so
-              it can try to eliminate it. }
+    { Notify the register allocator that we have written a move instruction so
+      it can try to eliminate it. }
     add_move_instruction(instr);
   end;
 end;
@@ -934,15 +933,11 @@ var
   tmpref: treference;
   tmpreg: tregister;
 begin
-  case size of
+  case tosize of
     OS_F32:
-    begin
       handle_load_store_fpu(list, False, A_LWC1, reg, ref);
-    end;
     OS_F64:
-    begin
       handle_load_store_fpu(list, False, A_LDC1, reg, ref);
-    end
     else
       InternalError(2007042701);
   end;
@@ -953,15 +948,11 @@ var
   tmpref: treference;
   tmpreg: tregister;
 begin
-  case size of
+  case tosize of
     OS_F32:
-    begin
       handle_load_store_fpu(list, True, A_SWC1, reg, ref);
-    end;
     OS_F64:
-    begin
       handle_load_store_fpu(list, True, A_SDC1, reg, ref);
-    end
     else
       InternalError(2007042702);
   end;
@@ -1237,59 +1228,58 @@ begin
   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;{ case }
+    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;
   list.Concat(TAiCpu.Op_none(A_NOP));
-
 end;
 
 
 procedure TCgMPSel.a_cmp_reg_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);
 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);
+    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 }
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
@@ -1297,7 +1287,7 @@ end;
 
 procedure TCgMPSel.a_jmp_always(List: tasmlist; l: TAsmLabel);
 begin
-  List.Concat(TAiCpu.op_sym(A_J, objectlibrary.newasmsymbol(l.Name, AB_EXTERNAL, AT_FUNCTION)));
+  List.Concat(TAiCpu.op_sym(A_J,l));
   { Delay slot }
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
@@ -1305,7 +1295,7 @@ end;
 
 procedure TCgMPSel.a_jmp_name(list: tasmlist; const s: string);
 begin
-  List.Concat(TAiCpu.op_sym(A_J, objectlibrary.newasmsymbol(s, AB_EXTERNAL, AT_FUNCTION)));
+  List.Concat(TAiCpu.op_sym(A_J, current_asmdata.RefAsmSymbol(s)));
   { Delay slot }
   list.Concat(TAiCpu.Op_none(A_NOP));
 end;
@@ -1410,9 +1400,9 @@ var
   localsize: aint;
 begin
   localsize := cgcpu_calc_stackframe_size;
-  if paramanager.ret_in_param(current_procinfo.procdef.rettype.def, current_procinfo.procdef.proccalloption) then
+  if paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption) then
   begin
-    reference_reset(hr);
+    reference_reset(hr,sizeof(aint));
     hr.offset  := 12;
     hr.refaddr := addr_full;
     if nostackframe then
@@ -1488,7 +1478,7 @@ begin
   paramanager.freeparaloc(list, paraloc1);
   alloccpuregisters(list, R_INTREGISTER, paramanager.get_volatile_registers_int(pocall_default));
   alloccpuregisters(list, R_FPUREGISTER, paramanager.get_volatile_registers_fpu(pocall_default));
-  a_call_name(list, 'FPC_MOVE');
+  a_call_name(list, 'FPC_MOVE', false);
   dealloccpuregisters(list, R_FPUREGISTER, paramanager.get_volatile_registers_fpu(pocall_default));
   dealloccpuregisters(list, R_INTREGISTER, paramanager.get_volatile_registers_int(pocall_default));
   paraloc3.done;
@@ -1511,8 +1501,8 @@ begin
     g_concatcopy_move(list, Source, dest, len)
   else
   begin
-    reference_reset(src);
-    reference_reset(dst);
+    reference_reset(src,sizeof(aint));
+    reference_reset(dst,sizeof(aint));
     { load the address of source into src.base }
     src.base := GetAddressRegister(list);
     a_loadaddr_ref_reg(list, Source, src.base);
@@ -1532,7 +1522,7 @@ begin
       a_load_const_reg(list, OS_INT, Count, countreg);
       { explicitely allocate R_O0 since it can be used safely here }
       { (for holding date that's being copied)                    }
-      objectlibrary.getlabel(lab);
+      current_asmdata.getjumplabel(lab);
       a_label(list, lab);
       list.concat(taicpu.op_reg_ref(A_LW, tmpreg1, src));
       list.concat(taicpu.op_reg_ref(A_SW, tmpreg1, dst));
@@ -1595,8 +1585,8 @@ begin
     g_concatcopy_move(list, Source, dest, len)
   else
   begin
-    reference_reset(src);
-    reference_reset(dst);
+    reference_reset(src,sizeof(aint));
+    reference_reset(dst,sizeof(aint));
     { load the address of source into src.base }
     src.base := GetAddressRegister(list);
     a_loadaddr_ref_reg(list, Source, src.base);
@@ -1615,7 +1605,7 @@ begin
       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)                    }
-      objectlibrary.getlabel(lab);
+      current_asmdata.getjumplabel(lab);
       a_label(list, lab);
       list.concat(taicpu.op_reg_ref(A_LBU, tmpreg1, src));
       list.concat(taicpu.op_reg_ref(A_SB, tmpreg1, dst));
@@ -1646,7 +1636,7 @@ procedure TCgMPSel.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const label
         var
           href: treference;
         begin
-          reference_reset_base(href, NR_R2, 0);  { return value }
+          reference_reset_base(href, NR_R2, 0, sizeof(aint));  { return value }
           cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24);
         end;
 
@@ -1658,7 +1648,7 @@ procedure TCgMPSel.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const label
           if (procdef.extnumber=$ffff) then
             Internalerror(200006139);
           { call/jmp  vmtoffs(%eax) ; method offs }
-          reference_reset_base(href, NR_R24, procdef._class.vmtmethodoffset(procdef.extnumber));
+          reference_reset_base(href, NR_R24, procdef._class.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));
         end;
@@ -1694,7 +1684,7 @@ begin
     op_onr24methodaddr;
   end
   else
-   list.concat(taicpu.op_sym(A_B, objectlibrary.newasmsymbol(procdef.mangledname, AB_EXTERNAL, AT_FUNCTION)));
+   list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(procdef.mangledname)));
   { Delay slot }
   list.Concat(TAiCpu.Op_none(A_NOP));
 
@@ -1966,7 +1956,10 @@ begin
 end;
 
 
-begin
-  cg   := TCgMPSel.Create;
-  cg64 := TCg64MPSel.Create;
+    procedure create_codegen;
+      begin
+        cg:=TCgMPSel.Create;
+        cg64:=TCg64MPSel.Create;
+      end;
+
 end.

+ 23 - 0
compiler/mips/cpubase.pas

@@ -296,11 +296,21 @@ unit cpubase;
       }
       std_param_align = 4;
 
+{*****************************************************************************
+                            CPU Dependent Constants
+*****************************************************************************}
+
+    const
+      simm16lo =  -32768;
+      simm16hi =   32767;
 
 {*****************************************************************************
                                   Helpers
 *****************************************************************************}
 
+    function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+    function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+
     { Returns the tcgsize corresponding with the size of reg.}
     function reg_cgsize(const reg: tregister) : tcgsize;
     function cgsize2subreg(regtype: tregistertype; s:tcgsize):tsubregister;
@@ -309,6 +319,10 @@ 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
@@ -386,6 +400,12 @@ unit cpubase;
       end;
 
 
+    function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+      begin
+        result := c1 = c2;
+      end;
+
+
     function std_regnum_search(const s:string):Tregister;
       begin
         result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];
@@ -404,4 +424,7 @@ unit cpubase;
       end;
 
 
+begin
+  STK2_dummy := 10;
+  STK2_Localsize := 0;
 end.

+ 246 - 0
compiler/mips/cpugas.pas

@@ -0,0 +1,246 @@
+{
+    Copyright (c) 1999-2009 by Florian Klaempfl and David Zhang
+
+    This unit implements an asmoutput class for MIPS assembly syntax
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpugas;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+  cpubase,
+  aasmtai, aasmcpu, assemble, aggas;
+
+type
+  TGasMIPSEL = class(TGnuAssembler)
+    procedure WriteInstruction(hp: Tai); override;
+  end;
+
+implementation
+
+uses
+  cutils, systems,
+  verbose, itcpugas, cgbase, cgutils;
+
+function GetReferenceString(var ref: TReference): string;
+begin
+  GetReferenceString := '';
+  with ref do
+  begin
+    if (base = NR_NO) and (index = NR_NO) then
+    begin
+      if assigned(symbol) then
+        GetReferenceString := symbol.Name;
+      if offset > 0 then
+        GetReferenceString := GetReferenceString + '+' + ToStr(offset)
+      else if offset < 0 then
+        GetReferenceString := GetReferenceString + ToStr(offset);
+      case refaddr of
+        addr_hi:
+          GetReferenceString := '%hi(' + GetReferenceString + ')';
+        addr_lo:
+          GetReferenceString := '%lo(' + GetReferenceString + ')';
+      end;
+    end
+    else
+    begin
+{$ifdef extdebug}
+      if assigned(symbol) and
+        not(refaddr in [addr_pic,addr_lo]) then
+        internalerror(2003052601);
+{$endif extdebug}
+      if base <> NR_NO then
+        GetReferenceString := GetReferenceString + '(' + gas_regname(base) + ')';
+      if index = NR_NO then
+      begin
+        if offset <> 0 then
+          GetReferenceString := ToStr(offset) + GetReferenceString;
+        if assigned(symbol) then
+        begin
+          if refaddr = addr_lo then
+            GetReferenceString := '%lo(' + symbol.Name + ')' + GetReferenceString
+          else
+            GetReferenceString := symbol.Name + {'+' +} GetReferenceString;
+        end;
+      end
+      else
+      begin
+{$ifdef extdebug}
+                    if (Offset<>0) or assigned(symbol) then
+                      internalerror(2003052603);
+{$endif extdebug}
+        GetReferenceString := GetReferenceString + '(' + gas_regname(index) + ')';
+
+      end;
+    end;
+  end;
+end;
+
+
+function getopstr(const Oper: TOper): string;
+begin
+  with Oper do
+    case typ of
+      top_reg:
+        getopstr := gas_regname(reg);
+      top_const:
+        getopstr := tostr(longint(val));
+      top_ref:
+        if (oper.ref^.refaddr in [addr_no, addr_pic]) or ((oper.ref^.refaddr = addr_lo) and ((oper.ref^.base <> NR_NO) or
+          (oper.ref^.index <> NR_NO))) then
+          getopstr := getreferencestring(ref^)
+        else
+          getopstr := getreferencestring(ref^);
+      else
+        internalerror(10001);
+    end;
+end;
+
+function getopstr_4(const Oper: TOper): string;
+var
+  tmpref: treference;
+begin
+  with Oper do
+    case typ of
+      top_ref:
+      begin
+        tmpref := ref^;
+        Inc(tmpref.offset, 4);
+        getopstr_4 := getreferencestring(tmpref);
+      end;
+      else
+        internalerror(2007050403);
+    end;
+end;
+
+
+procedure TGasMIPSEL.WriteInstruction(hp: Tai);
+var
+  Op: TAsmOp;
+  s,s1:  string;
+  i:  integer;
+  tmpfpu: string;
+  tmpfpu_len: longint;
+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 + std_op2str[A_ADDIU] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[1]^) + ',' + s1;
+      AsmWriteLn(s);
+    end;
+    A_P_FRAME:
+    begin
+    end;
+    A_P_SET_MACRO:
+    begin
+      s := #9 + '.set' + #9 + 'macro';
+      AsmWriteLn(s);
+    end;
+    A_P_SET_REORDER:
+    begin
+      s := #9 + '.set' + #9 + 'reorder';
+      AsmWriteLn(s);
+    end;
+    A_P_SET_NOMACRO:
+    begin
+      s := #9 + '.set' + #9 + 'nomacro';
+      AsmWriteLn(s);
+    end;
+    A_P_SET_NOREORDER:
+    begin
+      s := #9 + '.set' + #9 + 'noreorder';
+      AsmWriteLn(s);
+    end;
+    A_P_SW:
+    begin
+      s := #9 + std_op2str[A_SW] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
+      AsmWriteLn(s);
+    end;
+    A_P_LW:
+    begin
+      s := #9 + std_op2str[A_LW] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
+      AsmWriteLn(s);
+    end;
+    A_LDC1:
+    begin
+      tmpfpu := getopstr(taicpu(hp).oper[0]^);
+      s := #9 + std_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
+      AsmWriteLn(s);
+
+      tmpfpu_len := length(tmpfpu);
+      tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]);
+      s := #9 + std_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
+      AsmWriteLn(s);
+    end;
+    A_SDC1:
+    begin
+      tmpfpu := getopstr(taicpu(hp).oper[0]^);
+      s := #9 + std_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
+      AsmWriteLn(s);
+
+      tmpfpu_len := length(tmpfpu);
+      tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]);
+      s := #9 + std_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
+      AsmWriteLn(s);
+    end;
+    else
+    begin
+      s := #9 + std_op2str[op] + cond2str[taicpu(hp).condition];
+      if taicpu(hp).delayslot_annulled then
+        s := s + ',a';
+      if taicpu(hp).ops > 0 then
+      begin
+        s := s + #9 + getopstr(taicpu(hp).oper[0]^);
+        for i := 1 to taicpu(hp).ops - 1 do
+          s := s + ',' + getopstr(taicpu(hp).oper[i]^);
+      end;
+      AsmWriteLn(s);
+    end;
+  end;
+end;
+
+
+const
+  as_MIPSEL_as_info: tasminfo =
+    (
+    id: as_gas;
+    idtxt: 'AS';
+    asmbin: 'as';
+    asmcmd: '-mips2 -W -EL -o $OBJ $ASM';
+    supported_target: system_any;
+    flags: [af_allowdirect, af_needar, af_smartlink_sections];
+    labelprefix: '.L';
+    comment: '# ';
+    );
+
+begin
+  RegisterAssembler(as_MIPSEL_as_info, TGasMIPSEL);
+end.

+ 41 - 0
compiler/mips/cpunode.pas

@@ -0,0 +1,41 @@
+{******************************************************************************
+    Copyright (c) 2000 by Florian Klaempfl
+
+    Includes the MIPS code generator
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ *****************************************************************************}
+unit CpuNode;
+
+{$I fpcdefs.inc}
+
+interface
+{ This unit is used to define the specific CPU implementations. All needed
+actions are included in the INITALIZATION part of these units. This explains
+the behaviour of such a unit having just a USES clause! }
+
+implementation
+
+  uses
+    { generic nodes }
+    ncgbas,ncgld,ncgflw,ncgcnv,ncgmem,ncgcon,ncgcal,ncgset,ncginl,ncgopt,ncgmat,ncgobjc,
+    { to be able to only parts of the generic code,
+      the processor specific nodes must be included
+      after the generic one (FK)
+    }
+    ncpuadd,ncpucall,ncpumat,ncpuinln,ncpucnv,ncpuset;
+
+end.

+ 598 - 0
compiler/mips/ncpuadd.pas

@@ -0,0 +1,598 @@
+{
+    Copyright (c) 2000-2009 by Florian Klaempfl and David Zhang
+
+    Code generation for add nodes on the FVM32
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit ncpuadd;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+  node, ncgadd, cpubase, aasmbase, cgbase;
+
+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;
+  protected
+    procedure second_addfloat; override;
+    procedure second_cmpfloat; override;
+    procedure second_cmpboolean; override;
+    procedure second_cmpsmallset; override;
+    procedure second_cmp64bit; override;
+    procedure second_cmpordinal; override;
+  end;
+
+implementation
+
+uses
+  systems,
+  cutils, verbose,
+  paramgr,
+  aasmtai, aasmcpu, aasmdata,
+  defutil,
+  {cgbase,} cgcpu, cgutils,
+  cpupara,
+  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;
+begin
+
+  objectlibrary.getlabel(lfcmp64_L4);
+
+  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.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_none(A_NOP));
+
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
+  cmp64_eq := NR_TCR10;
+end;
+
+function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
+var
+  lfcmp64_L4: tasmlabel;
+begin
+
+  objectlibrary.getlabel(lfcmp64_L4);
+
+  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.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_none(A_NOP));
+
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
+  cmp64_ne := NR_TCR10;
+end;
+
+function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
+var
+  lfcmp64_L4, lfcmp64_L5: tasmlabel;
+begin
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+
+  objectlibrary.getlabel(lfcmp64_L4);
+  objectlibrary.getlabel(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_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_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_none(A_NOP));
+  current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, 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));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
+  cmp64_lt := NR_TCR10;
+end;
+
+function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister;
+var
+  lfcmp64_L4, lfcmp64_L5: tasmlabel;
+begin
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+
+  objectlibrary.getlabel(lfcmp64_L4);
+  objectlibrary.getlabel(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_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_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_none(A_NOP));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
+  cmp64_le := NR_TCR10;
+end;
+
+function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
+var
+  lfcmp64_L4, lfcmp64_L5: tasmlabel;
+begin
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+
+  objectlibrary.getlabel(lfcmp64_L4);
+  objectlibrary.getlabel(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_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_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_none(A_NOP));
+  current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, 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));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
+  cmp64_ltu := NR_TCR10;
+end;
+
+function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
+var
+  lfcmp64_L4, lfcmp64_L5: tasmlabel;
+begin
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
+
+  objectlibrary.getlabel(lfcmp64_L4);
+  objectlibrary.getlabel(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_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_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_none(A_NOP));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
+
+  cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
+  cmp64_leu := NR_TCR10;
+end;
+
+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;
+    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;
+      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;
+      end;
+  end;
+end;
+
+procedure tmipsaddnode.second_addfloat;
+var
+  op: TAsmOp;
+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, (left.location.loc <> LOC_CFPUREGISTER));
+
+  location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef));
+  if left.location.loc <> LOC_CFPUREGISTER then
+    location.Register := left.location.Register
+  else
+    location.Register := right.location.Register;
+
+  case nodetype of
+    addn:
+    begin
+      if location.size = OS_F64 then
+        op := A_ADD_D
+      else
+        op := A_ADD_S;
+    end;
+    muln:
+    begin
+      if location.size = OS_F64 then
+        op := A_MUL_D
+      else
+        op := A_MUL_S;
+    end;
+    subn:
+    begin
+      if location.size = OS_F64 then
+        op := A_SUB_D
+      else
+        op := A_SUB_S;
+    end;
+    slashn:
+    begin
+      if location.size = OS_F64 then
+        op := A_DIV_D
+      else
+        op := A_DIV_S;
+    end;
+    else
+      internalerror(200306014);
+  end;
+  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,
+    location.Register, left.location.Register, right.location.Register));
+
+end;
+
+
+procedure tmipsaddnode.second_cmpfloat;
+var
+  op: tasmop;
+  lfcmptrue, lfcmpfalse: tasmlabel;
+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_REGISTER, OS_INT);
+  location.Register := NR_TCR0;
+
+  case NodeType of
+    equaln:
+    begin
+      if left.location.size = OS_F64 then
+        op := A_C_EQ_D
+      else
+        op := A_C_EQ_S;
+      objectlibrary.getlabel(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(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));
+      cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
+
+    end;
+    unequaln:
+    begin
+      if left.location.size = OS_F64 then
+        op := A_C_EQ_D
+      else
+        op := A_C_EQ_S;
+      objectlibrary.getlabel(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(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));
+      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;
+      objectlibrary.getlabel(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(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));
+      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;
+      objectlibrary.getlabel(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(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));
+      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;
+      objectlibrary.getlabel(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(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));
+      cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
+    end;
+    gten:
+    begin
+      if left.location.size = OS_F64 then
+        op := A_C_LE_D
+      else
+        op := A_C_LE_S;
+      objectlibrary.getlabel(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(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));
+      cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
+    end;
+  end; {case}
+end;
+
+
+procedure tmipsaddnode.second_cmpboolean;
+var
+  tmp_right_reg: TRegister;
+begin
+  pass_left_right;
+  force_reg_left_right(True, True);
+  tmp_right_reg := NR_NO;
+  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, NR_TCR0, left.location.Register, tmp_right_reg);
+
+end;
+
+
+procedure tmipsaddnode.second_cmpsmallset;
+var
+  tmp_right_reg: TRegister;
+begin
+  pass_left_right;
+  force_reg_left_right(True, True);
+
+  tmp_right_reg := NR_NO;
+
+  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, NR_TCR0, 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, {NR_TCR0, }left.location.register64, right.location.register64); // NR_TCR0;
+end;
+
+
+procedure tmipsaddnode.second_cmpordinal;
+var
+  unsigned: boolean;
+  tmp_right_reg: 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;
+  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(unsigned, NR_TCR0, left.location.Register, tmp_right_reg);
+end;
+
+begin
+  caddnode := tmipsaddnode;
+end.

+ 4 - 0
compiler/ncgutil.pas

@@ -488,8 +488,10 @@ implementation
                hregister:=cg.getintregister(list,OS_INT);
               { load value in low register }
               case l.loc of
+{$ifdef cpuflags}
                 LOC_FLAGS :
                   cg.g_flags2reg(list,OS_INT,l.resflags,hregister);
+{$endif cpuflags}
                 LOC_JUMP :
                   begin
                     cg.a_label(list,current_procinfo.CurrTrueLabel);
@@ -574,8 +576,10 @@ implementation
              hregister := l.register;
            { load value in new register }
            case l.loc of
+{$ifdef cpuflags}
              LOC_FLAGS :
                cg.g_flags2reg(list,dst_size,l.resflags,hregister);
+{$endif cpuflags}
              LOC_JUMP :
                begin
                  cg.a_label(list,current_procinfo.CurrTrueLabel);

+ 5 - 7
compiler/rgobj.pas

@@ -1805,10 +1805,9 @@ unit rgobj;
       end;
 
 
-    procedure Trgobj.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
-
-    var ins:Taicpu;
-
+    procedure trgobj.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
+      var
+        ins:Taicpu;
       begin
         ins:=spilling_create_load(spilltemp,tempreg);
         add_cpu_interferences(ins);
@@ -1817,9 +1816,8 @@ unit rgobj;
 
 
     procedure Trgobj.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
-
-    var ins:Taicpu;
-
+      var
+        ins:Taicpu;
       begin
         ins:=spilling_create_store(tempreg,spilltemp);
         add_cpu_interferences(ins);