DYNAREC: More work on DIV, no effect
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / new_dynarec / new_dynarec.c
index 9a5226e..e76e4c9 100755 (executable)
@@ -49,7 +49,7 @@
 
 #define MAXBLOCK 4096
 #define MAX_OUTPUT_BLOCK_SIZE 262144
-#define CLOCK_DIVIDER 2
+#define CLOCK_DIVIDER count_per_op
 
 void *base_addr;
 
@@ -272,7 +272,7 @@ static int verify_dirty(void *addr);
 //#define DEBUG_CYCLE_COUNT 1
 
 // Uncomment these two lines to generate debug output:
-//#define ASSEM_DEBUG 1
+#//define ASSEM_DEBUG 1
 //#define INV_DEBUG 1
 
 // Uncomment this line to output the number of NOTCOMPILED blocks as they occur:
@@ -845,24 +845,58 @@ static void alloc_all(struct regstat *cur,int i)
 
 static void div64(int64_t dividend,int64_t divisor)
 {
+  if ((dividend) && (divisor)) {
   lo=dividend/divisor;
   hi=dividend%divisor;
+  } else {
+  lo=0;
+  hi=0;
+  }
   //DebugMessage(M64MSG_VERBOSE, "TRACE: ddiv %8x%8x %8x%8x" ,(int)reg[HIREG],(int)(reg[HIREG]>>32)
   //                                     ,(int)reg[LOREG],(int)(reg[LOREG]>>32));
 }
 static void divu64(uint64_t dividend,uint64_t divisor)
 {
+  if ((dividend) && (divisor)) {
+  lo=dividend/divisor;
+  hi=dividend%divisor;
+  } else {
+  lo=0;
+  hi=0;
+  }
+  //DebugMessage(M64MSG_VERBOSE, "TRACE: ddivu %8x%8x %8x%8x",(int)reg[HIREG],(int)(reg[HIREG]>>32)
+  //                                     ,(int)reg[LOREG],(int)(reg[LOREG]>>32));
+}
+static void div32(int32_t dividend,int32_t divisor)
+{
+  if ((dividend) && (divisor)) {
   lo=dividend/divisor;
   hi=dividend%divisor;
+  } else {
+  lo=0;
+  hi=0;
+  }
+  //DebugMessage(M64MSG_VERBOSE, "TRACE: ddiv %8x%8x %8x%8x" ,(int)reg[HIREG],(int)(reg[HIREG]>>32)
+  //                                     ,(int)reg[LOREG],(int)(reg[LOREG]>>32));
+}
+static void divu32(uint32_t dividend,uint32_t divisor)
+{
+  if ((dividend) && (divisor)) {
+  lo=dividend/divisor;
+  hi=dividend%divisor;
+  } else {
+  lo=0;
+  hi=0;
+  }
   //DebugMessage(M64MSG_VERBOSE, "TRACE: ddivu %8x%8x %8x%8x",(int)reg[HIREG],(int)(reg[HIREG]>>32)
   //                                     ,(int)reg[LOREG],(int)(reg[LOREG]>>32));
 }
 
 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;
-   unsigned long long int temp1, temp2, temp3, temp4;
+   uint64_t op1, op2, op3, op4;
+   uint64_t result1, result2, result3, result4;
+   uint64_t temp1, temp2, temp3, temp4;
    int sign = 0;
    
    if (m1 < 0)
@@ -906,9 +940,9 @@ static void mult64(int64_t m1,int64_t m2)
 #if NEW_DYNAREC == NEW_DYNAREC_ARM
 static void multu64(uint64_t m1,uint64_t m2)
 {
-   unsigned long long int op1, op2, op3, op4;
-   unsigned long long int result1, result2, result3, result4;
-   unsigned long long int temp1, temp2, temp3, temp4;
+   uint64_t op1, op2, op3, op4;
+   uint64_t result1, result2, result3, result4;
+   uint64_t temp1, temp2, temp3, temp4;
    
    op1 = m1 & 0xFFFFFFFF;
    op2 = (m1 >> 32) & 0xFFFFFFFF;
@@ -1728,6 +1762,7 @@ void multdiv_alloc(struct regstat *current,int i)
       current->uu&=~(1LL<<HIREG);
       current->uu&=~(1LL<<LOREG);
       alloc_reg64(current,i,HIREG);
+         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]);
@@ -1744,10 +1779,18 @@ 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;
+       if((opcode2[i]&4)==0) // 32-bit
+       {
+               alloc_reg(current,i,HIREG);
+               alloc_reg(current,i,LOREG);
+               current->is32|=1LL<<HIREG;
+               current->is32|=1LL<<LOREG;
+       } else {
+               alloc_reg64(current,i,HIREG);
+               alloc_reg64(current,i,LOREG);
+               current->is32&=~(1LL<<HIREG);
+               current->is32&=~(1LL<<LOREG);
+       }
        dirty_reg(current,HIREG);
        dirty_reg(current,LOREG);
   }