CORE: Fixe DIV 64bits, remove assert so SUB 64bit with carry don't crash (still wrong...
authorptitSeb <sebastien.chev@gmail.com>
Tue, 22 Oct 2013 19:33:40 +0000 (21:33 +0200)
committerptitSeb <sebastien.chev@gmail.com>
Tue, 22 Oct 2013 19:33:40 +0000 (21:33 +0200)
source/mupen64plus-core/src/r4300/new_dynarec/assem_arm.c
source/mupen64plus-core/src/r4300/new_dynarec/new_dynarec.c [changed mode: 0644->0755]

index 2f1fb83..560fc52 100755 (executable)
@@ -1288,9 +1288,9 @@ static void emit_adcimm(u_int rs,int imm,u_int rt)
   output_w32(0xe2c00000|rd_rn_rm(rt,rt,0)|armval);
 }*/
 
-static void emit_rscimm(int rs,int imm,u_int rt)
+static void emit_rscimm(int rs,int imm,u_int rt)       //*SEB* why the assert(0) here?
 {
-  assert(0);
+//  assert(0);
   u_int armval, ret;
   ret = genimm(imm,&armval);
   assert(ret);
@@ -4151,7 +4151,7 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs)
     {
       if(opcode2[i]==0x1C) // DMULT
       {
-        assert(opcode2[i]!=0x1C);
+        //assert(opcode2[i]!=0x1C);
         signed char m1h=get_reg(i_regs->regmap,rs1[i]|64);
         signed char m1l=get_reg(i_regs->regmap,rs1[i]);
         signed char m2h=get_reg(i_regs->regmap,rs2[i]|64);
@@ -4160,15 +4160,16 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs)
         assert(m2h>=0);
         assert(m1l>=0);
         assert(m2l>=0);
-        emit_pushreg(m2h);
-        emit_pushreg(m2l);
-        emit_pushreg(m1h);
-        emit_pushreg(m1l);
+        save_regs(0x100f);
+        if(m1l!=0) emit_mov(m1l,0);
+        if(m1h==0) emit_readword((int)&dynarec_local,1);
+        else if(m1h>1) emit_mov(m1h,1);
+        if(m2l<2) emit_readword((int)&dynarec_local+m2l*4,2);
+        else if(m2l>2) emit_mov(m2l,2);
+        if(m2h<3) emit_readword((int)&dynarec_local+m2h*4,3);
+        else if(m2h>3) emit_mov(m2h,3);
         emit_call((int)&mult64);
-        emit_popreg(m1l);
-        emit_popreg(m1h);
-        emit_popreg(m2l);
-        emit_popreg(m2h);
+        restore_regs(0x100f);
         signed char hih=get_reg(i_regs->regmap,HIREG|64);
         signed char hil=get_reg(i_regs->regmap,HIREG);
         if(hih>=0) emit_loadreg(HIREG|64,hih);
@@ -4327,10 +4328,23 @@ static void multdiv_assemble_arm(int i,struct regstat *i_regs)
     // Multiply by zero is zero.
     // MIPS does not have a divide by zero exception.
     // The result is undefined, we return zero.
-    signed char hr=get_reg(i_regs->regmap,HIREG);
-    signed char lr=get_reg(i_regs->regmap,LOREG);
-    if(hr>=0) emit_zeroreg(hr);
-    if(lr>=0) emit_zeroreg(lr);
+/*    if((opcode2[i]&4)!=0) // 64-bit
+    {
+        signed char hih=get_reg(i_regs->regmap,HIREG|64);
+               signed char hr=get_reg(i_regs->regmap,HIREG);
+        signed char loh=get_reg(i_regs->regmap,LOREG|64);
+               signed char lr=get_reg(i_regs->regmap,LOREG);
+        if(hih>=0) emit_zeroreg(hih);
+               if(hr>=0) emit_zeroreg(hr);
+        if(loh>=0) emit_zeroreg(loh);
+               if(lr>=0) emit_zeroreg(lr);
+       } else */
+       {
+               signed char hr=get_reg(i_regs->regmap,HIREG);
+               signed char lr=get_reg(i_regs->regmap,LOREG);
+               if(hr>=0) emit_zeroreg(hr);
+               if(lr>=0) emit_zeroreg(lr);
+       }
   }
 }
 #define multdiv_assemble multdiv_assemble_arm
old mode 100644 (file)
new mode 100755 (executable)
index 8ee4eda..f9fbc40
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <stdint.h> //include for uint64_t
 #include <assert.h>
+//#define assert(a)    {}
 
 #include "../recomp.h"
 #include "../recomph.h" //include for function prototypes
@@ -857,7 +858,7 @@ static void divu64(uint64_t dividend,uint64_t divisor)
   //                                     ,(int)reg[LOREG],(int)(reg[LOREG]>>32));
 }
 
-static void mult64(uint64_t m1,uint64_t m2)
+static void mult64(int64_t m1,int64_t m2)
 {
    unsigned long long int op1, op2, op3, op4;
    unsigned long long int result1, result2, result3, result4;
@@ -1727,7 +1728,7 @@ void multdiv_alloc(struct regstat *current,int i)
       current->uu&=~(1LL<<HIREG);
       current->uu&=~(1LL<<LOREG);
       alloc_reg64(current,i,HIREG);
-      //if(HOST_REGS>10) alloc_reg64(current,i,LOREG);
+      //if(HOST_REGS>10) alloc_reg64(current,i,LOREG); //*SEB* Why commenting this line? uncommenting make SM64 freeze after title (before mario head and spinning stars)
       alloc_reg64(current,i,rs1[i]);
       alloc_reg64(current,i,rs2[i]);
       alloc_all(current,i);
@@ -1743,12 +1744,12 @@ void multdiv_alloc(struct regstat *current,int i)
     // Multiply by zero is zero.
     // MIPS does not have a divide by zero exception.
     // The result is undefined, we return zero.
-    alloc_reg(current,i,HIREG);
-    alloc_reg(current,i,LOREG);
-    current->is32|=1LL<<HIREG;
-    current->is32|=1LL<<LOREG;
-    dirty_reg(current,HIREG);
-    dirty_reg(current,LOREG);
+       alloc_reg(current,i,HIREG);
+       alloc_reg(current,i,LOREG);
+       current->is32|=1LL<<HIREG;
+       current->is32|=1LL<<LOREG;
+       dirty_reg(current,HIREG);
+       dirty_reg(current,LOREG);
   }
 }
 #endif
@@ -5305,6 +5306,7 @@ static void cjump_assemble(int i,struct regstat *i_regs)
         if(opcode[i]==6) // BLEZ
         {
           emit_test(s1h,s1h);
+//          emit_testimm(s1h,0);
           if(invert) taken=(int)out;
           else add_to_linker((int)out,ba[i],internal);
           emit_js(0);
@@ -5314,6 +5316,7 @@ static void cjump_assemble(int i,struct regstat *i_regs)
         if(opcode[i]==7) // BGTZ
         {
           emit_test(s1h,s1h);
+//          emit_testimm(s1h,0);
           nottaken1=(int)out;
           emit_js(1);
           if(invert) taken=(int)out;
@@ -9253,10 +9256,14 @@ int new_recompile_block(int addr)
       }
       // Don't need stuff which is overwritten
       if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
-      if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
+      if(regs[i].regmap[hr]<0) nr&=~(1<<hr);   //moved...
       // Merge in delay slot
       for(hr=0;hr<HOST_REGS;hr++)
       {
+               // Don't need stuff which is overwritten
+/*             if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr); //*SEB* Moved here
+               if(regs[i].regmap[hr]<0) nr&=~(1<<hr);*/
+
         if(!likely[i]) {
           // These are overwritten unless the branch is "likely"
           // and the delay slot is nullified if not taken