#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h> //include for uint64_t
-#include <assert.h>
+//#include <assert.h>
+#define assert(a) {}
#include "../recomp.h"
#include "../recomph.h" //include for function prototypes
#define MAXBLOCK 4096
#define MAX_OUTPUT_BLOCK_SIZE 262144
-#define CLOCK_DIVIDER 2
+#define CLOCK_DIVIDER count_per_op
void *base_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:
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(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;
- 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)
#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;
current->uu&=~(1LL<<HIREG);
current->uu&=~(1LL<<LOREG);
alloc_reg64(current,i,HIREG);
- //if(HOST_REGS>10) alloc_reg64(current,i,LOREG);
+ 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);
// 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);
+ 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);
}
}
#endif
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);
if(opcode[i]==7) // BGTZ
{
emit_test(s1h,s1h);
+// emit_testimm(s1h,0);
nottaken1=(int)out;
emit_js(1);
if(invert) taken=(int)out;
}
// 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