Beispiel #1
0
void gencfc1(void)
{
#ifdef INTERPRET_CFC1
   gencallinterp((native_type)cached_interpreter_table.CFC1, 0);
#else
   gencheck_cop1_unusable();
#ifdef __x86_64__
   if(dst->f.r.nrd == 31)
      mov_xreg32_m32rel(EAX, (unsigned int*)&FCR31);
   else
      mov_xreg32_m32rel(EAX, (unsigned int*)&FCR0);
   mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EAX);
   sar_reg32_imm8(EAX, 31);
   mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EAX);
#else
   if(dst->f.r.nrd == 31)
      mov_eax_memoffs32((unsigned int*)&FCR31);
   else
      mov_eax_memoffs32((unsigned int*)&FCR0);
   mov_memoffs32_eax((unsigned int*)dst->f.r.rt);
   sar_reg32_imm8(EAX, 31);
   mov_memoffs32_eax(((unsigned int*)dst->f.r.rt)+1);
#endif
#endif
}
Beispiel #2
0
void gendsrav(usf_state_t * state)
{
#ifdef INTERPRET_DSRAV
   gencallinterp(state, (unsigned int)state->current_instruction_table.DSRAV, 0);
#else
   int rt1, rt2, rd1, rd2;
   allocate_register_manually(state, ECX, (unsigned int *)state->dst->f.r.rs);
   
   rt1 = allocate_64_register1(state, (unsigned int *)state->dst->f.r.rt);
   rt2 = allocate_64_register2(state, (unsigned int *)state->dst->f.r.rt);
   rd1 = allocate_64_register1_w(state, (unsigned int *)state->dst->f.r.rd);
   rd2 = allocate_64_register2_w(state, (unsigned int *)state->dst->f.r.rd);
   
   if (rd1 != ECX && rd2 != ECX)
     {
    mov_reg32_reg32(state, rd1, rt1);
    mov_reg32_reg32(state, rd2, rt2);
    shrd_reg32_reg32_cl(state, rd1,rd2);
    sar_reg32_cl(state, rd2);
    test_reg32_imm32(state, ECX, 0x20);
    je_rj(state, 5);
    mov_reg32_reg32(state, rd1, rd2); // 2
    sar_reg32_imm8(state, rd2, 31); // 3
     }
   else
     {
    int temp1, temp2;
    force_32(state, ECX);
    temp1 = lru_register(state);
    temp2 = lru_register_exc1(state, temp1);
    free_register(state, temp1);
    free_register(state, temp2);
    
    mov_reg32_reg32(state, temp1, rt1);
    mov_reg32_reg32(state, temp2, rt2);
    shrd_reg32_reg32_cl(state, temp1, temp2);
    sar_reg32_cl(state, temp2);
    test_reg32_imm32(state, ECX, 0x20);
    je_rj(state, 5);
    mov_reg32_reg32(state, temp1, temp2); // 2
    sar_reg32_imm8(state, temp2, 31); // 3
    
    mov_reg32_reg32(state, rd1, temp1);
    mov_reg32_reg32(state, rd2, temp2);
     }
#endif
}
Beispiel #3
0
void gendsrav()
{
#ifdef INTERPRET_DSRAV
   gencallinterp((unsigned long)DSRAV, 0);
#else
   int rt1, rt2, rd1, rd2;
   allocate_register_manually(ECX, (unsigned long *)dst->f.r.rs);
   
   rt1 = allocate_64_register1((unsigned long *)dst->f.r.rt);
   rt2 = allocate_64_register2((unsigned long *)dst->f.r.rt);
   rd1 = allocate_64_register1_w((unsigned long *)dst->f.r.rd);
   rd2 = allocate_64_register2_w((unsigned long *)dst->f.r.rd);
   
   if (rd1 != ECX && rd2 != ECX)
     {
	mov_reg32_reg32(rd1, rt1);
	mov_reg32_reg32(rd2, rt2);
	shrd_reg32_reg32_cl(rd1,rd2);
	sar_reg32_cl(rd2);
	test_reg32_imm32(ECX, 0x20);
	je_rj(5);
	mov_reg32_reg32(rd1, rd2); // 2
	sar_reg32_imm8(rd2, 31); // 3
     }
   else
     {
	int temp1, temp2;
	force_32(ECX);
	temp1 = lru_register();
	temp2 = lru_register_exc1(temp1);
	free_register(temp1);
	free_register(temp2);
	
	mov_reg32_reg32(temp1, rt1);
	mov_reg32_reg32(temp2, rt2);
	shrd_reg32_reg32_cl(temp1, temp2);
	sar_reg32_cl(temp2);
	test_reg32_imm32(ECX, 0x20);
	je_rj(5);
	mov_reg32_reg32(temp1, temp2); // 2
	sar_reg32_imm8(temp2, 31); // 3
	
	mov_reg32_reg32(rd1, temp1);
	mov_reg32_reg32(rd2, temp2);
     }
#endif
}
Beispiel #4
0
// this function frees a specific X86 GPR
void free_register(int reg)
{
   struct precomp_instr *last;
   
   if (g_dev.r4300.regcache_state.last_access[reg] != NULL &&
       g_dev.r4300.regcache_state.r64[reg] != -1 && (int)g_dev.r4300.regcache_state.reg_content[reg] != (int)g_dev.r4300.regcache_state.reg_content[g_dev.r4300.regcache_state.r64[reg]]-4)
     {
    free_register(g_dev.r4300.regcache_state.r64[reg]);
    return;
     }
   
   if (g_dev.r4300.regcache_state.last_access[reg] != NULL) last = g_dev.r4300.regcache_state.last_access[reg]+1;
   else last = g_dev.r4300.regcache_state.free_since[reg];
   
   while (last <= g_dev.r4300.recomp.dst)
     {
    if (g_dev.r4300.regcache_state.last_access[reg] != NULL && g_dev.r4300.regcache_state.dirty[reg])
      last->reg_cache_infos.needed_registers[reg] = g_dev.r4300.regcache_state.reg_content[reg];
    else
      last->reg_cache_infos.needed_registers[reg] = NULL;
    
    if (g_dev.r4300.regcache_state.last_access[reg] != NULL && g_dev.r4300.regcache_state.r64[reg] != -1)
      {
         if (g_dev.r4300.regcache_state.dirty[g_dev.r4300.regcache_state.r64[reg]])
           last->reg_cache_infos.needed_registers[g_dev.r4300.regcache_state.r64[reg]] = g_dev.r4300.regcache_state.reg_content[g_dev.r4300.regcache_state.r64[reg]];
         else
           last->reg_cache_infos.needed_registers[g_dev.r4300.regcache_state.r64[reg]] = NULL;
      }
    
    last++;
     }
   if (g_dev.r4300.regcache_state.last_access[reg] == NULL) 
     {
    g_dev.r4300.regcache_state.free_since[reg] = g_dev.r4300.recomp.dst+1;
    return;
     }
   
   if (g_dev.r4300.regcache_state.dirty[reg]) 
     {
    mov_m32_reg32(g_dev.r4300.regcache_state.reg_content[reg], reg);
    if (g_dev.r4300.regcache_state.r64[reg] == -1)
      {
         sar_reg32_imm8(reg, 31);
         mov_m32_reg32((unsigned int*)g_dev.r4300.regcache_state.reg_content[reg]+1, reg);
      }
    else mov_m32_reg32(g_dev.r4300.regcache_state.reg_content[g_dev.r4300.regcache_state.r64[reg]], g_dev.r4300.regcache_state.r64[reg]);
     }
   g_dev.r4300.regcache_state.last_access[reg] = NULL;
   g_dev.r4300.regcache_state.free_since[reg] = g_dev.r4300.recomp.dst+1;
   if (g_dev.r4300.regcache_state.r64[reg] != -1)
     {
    g_dev.r4300.regcache_state.last_access[g_dev.r4300.regcache_state.r64[reg]] = NULL;
    g_dev.r4300.regcache_state.free_since[g_dev.r4300.regcache_state.r64[reg]] = g_dev.r4300.recomp.dst+1;
     }
}
Beispiel #5
0
// this function frees a specific X86 GPR
void free_register(usf_state_t * state, int reg)
{
   precomp_instr *last;
   
   if (state->last_access[reg] != NULL &&
       state->r64[reg] != -1 && (int)state->reg_content[reg] != (int)state->reg_content[state->r64[reg]]-4)
     {
    free_register(state, state->r64[reg]);
    return;
     }
   
   if (state->last_access[reg] != NULL) last = state->last_access[reg]+1;
   else last = state->free_since[reg];
   
   while (last <= state->dst)
     {
    if (state->last_access[reg] != NULL && state->dirty[reg])
      last->reg_cache_infos.needed_registers[reg] = state->reg_content[reg];
    else
      last->reg_cache_infos.needed_registers[reg] = NULL;
    
    if (state->last_access[reg] != NULL && state->r64[reg] != -1)
      {
         if (state->dirty[state->r64[reg]])
           last->reg_cache_infos.needed_registers[state->r64[reg]] = state->reg_content[state->r64[reg]];
         else
           last->reg_cache_infos.needed_registers[state->r64[reg]] = NULL;
      }
    
    last++;
     }
   if (state->last_access[reg] == NULL)
     {
    state->free_since[reg] = state->dst+1;
    return;
     }
   
   if (state->dirty[reg])
     {
    mov_m32_reg32(state, state->reg_content[reg], reg);
    if (state->r64[reg] == -1)
      {
         sar_reg32_imm8(state, reg, 31);
         mov_m32_reg32(state, (unsigned int*)state->reg_content[reg]+1, reg);
      }
    else mov_m32_reg32(state, state->reg_content[state->r64[reg]], state->r64[reg]);
     }
   state->last_access[reg] = NULL;
   state->free_since[reg] = state->dst+1;
   if (state->r64[reg] != -1)
     {
    state->last_access[state->r64[reg]] = NULL;
    state->free_since[state->r64[reg]] = state->dst+1;
     }
}
Beispiel #6
0
// this function frees a specific X86 GPR
void free_register(int reg)
{
   precomp_instr *last;
   
   if (last_access[reg] != NULL &&
       r64[reg] != -1 && (int)reg_content[reg] != (int)reg_content[r64[reg]]-4)
     {
    free_register(r64[reg]);
    return;
     }
   
   if (last_access[reg] != NULL) last = last_access[reg]+1;
   else last = free_since[reg];
   
   while (last <= dst)
     {
    if (last_access[reg] != NULL && dirty[reg])
      last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
    else
      last->reg_cache_infos.needed_registers[reg] = NULL;
    
    if (last_access[reg] != NULL && r64[reg] != -1)
      {
         if (dirty[r64[reg]])
           last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
         else
           last->reg_cache_infos.needed_registers[r64[reg]] = NULL;
      }
    
    last++;
     }
   if (last_access[reg] == NULL) 
     {
    free_since[reg] = dst+1;
    return;
     }
   
   if (dirty[reg]) 
     {
    mov_m32_reg32(reg_content[reg], reg);
    if (r64[reg] == -1)
      {
         sar_reg32_imm8(reg, 31);
         mov_m32_reg32((unsigned int*)reg_content[reg]+1, reg);
      }
    else mov_m32_reg32(reg_content[r64[reg]], r64[reg]);
     }
   last_access[reg] = NULL;
   free_since[reg] = dst+1;
   if (r64[reg] != -1)
     {
    last_access[r64[reg]] = NULL;
    free_since[r64[reg]] = dst+1;
     }
}
Beispiel #7
0
void gendsra(usf_state_t * state)
{
#ifdef INTERPRET_DSRA
   gencallinterp(state, (unsigned int)state->current_instruction_table.DSRA, 0);
#else
   int rt1 = allocate_64_register1(state, (unsigned int *)state->dst->f.r.rt);
   int rt2 = allocate_64_register2(state, (unsigned int *)state->dst->f.r.rt);
   int rd1 = allocate_64_register1_w(state, (unsigned int *)state->dst->f.r.rd);
   int rd2 = allocate_64_register2_w(state, (unsigned int *)state->dst->f.r.rd);
   
   mov_reg32_reg32(state, rd1, rt1);
   mov_reg32_reg32(state, rd2, rt2);
   shrd_reg32_reg32_imm8(state, rd1, rd2, state->dst->f.r.sa);
   sar_reg32_imm8(state, rd2, state->dst->f.r.sa);
   if (state->dst->f.r.sa & 0x20)
     {
    mov_reg32_reg32(state, rd1, rd2);
    sar_reg32_imm8(state, rd2, 31);
     }
#endif
}
Beispiel #8
0
void gensra(usf_state_t * state)
{
#ifdef INTERPRET_SRA
   gencallinterp(state, (unsigned int)state->current_instruction_table.SRA, 0);
#else
   int rt = allocate_register(state, (unsigned int *)state->dst->f.r.rt);
   int rd = allocate_register_w(state, (unsigned int *)state->dst->f.r.rd);
   
   mov_reg32_reg32(state, rd, rt);
   sar_reg32_imm8(state, rd, state->dst->f.r.sa);
#endif
}
Beispiel #9
0
void genmfc1(void)
{
#ifdef INTERPRET_MFC1
   gencallinterp((native_type)cached_interpreter_table.MFC1, 0);
#else
   gencheck_cop1_unusable();
#ifdef __x86_64__
   mov_xreg64_m64rel(RAX, (unsigned long long*)(&reg_cop1_simple[dst->f.r.nrd]));
   mov_reg32_preg64(EBX, RAX);
   mov_m32rel_xreg32((uint32_t*)dst->f.r.rt, EBX);
   sar_reg32_imm8(EBX, 31);
   mov_m32rel_xreg32(((uint32_t*)dst->f.r.rt)+1, EBX);
#else
   mov_eax_memoffs32((unsigned int*)(&reg_cop1_simple[dst->f.r.nrd]));
   mov_reg32_preg32(EBX, EAX);
   mov_m32_reg32((unsigned int*)dst->f.r.rt, EBX);
   sar_reg32_imm8(EBX, 31);
   mov_m32_reg32(((unsigned int*)dst->f.r.rt)+1, EBX);
#endif
#endif
}
Beispiel #10
0
void gendsra(void)
{
#ifdef INTERPRET_DSRA
   gencallinterp((unsigned int)cached_interpreter_table.DSRA, 0);
#else
   int rt1 = allocate_64_register1((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rd1 = allocate_64_register1_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   int rd2 = allocate_64_register2_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   
   mov_reg32_reg32(rd1, rt1);
   mov_reg32_reg32(rd2, rt2);
   shrd_reg32_reg32_imm8(rd1, rd2, g_dev.r4300.recomp.dst->f.r.sa);
   sar_reg32_imm8(rd2, g_dev.r4300.recomp.dst->f.r.sa);
   if (g_dev.r4300.recomp.dst->f.r.sa & 0x20)
     {
    mov_reg32_reg32(rd1, rd2);
    sar_reg32_imm8(rd2, 31);
     }
#endif
}
Beispiel #11
0
void gendsra()
{
#ifdef INTERPRET_DSRA
   gencallinterp((unsigned long)DSRA, 0);
#else
   int rt1 = allocate_64_register1((unsigned long *)dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned long *)dst->f.r.rt);
   int rd1 = allocate_64_register1_w((unsigned long *)dst->f.r.rd);
   int rd2 = allocate_64_register2_w((unsigned long *)dst->f.r.rd);
   
   mov_reg32_reg32(rd1, rt1);
   mov_reg32_reg32(rd2, rt2);
   shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa);
   sar_reg32_imm8(rd2, dst->f.r.sa);
   if (dst->f.r.sa & 0x20)
     {
	mov_reg32_reg32(rd1, rd2);
	sar_reg32_imm8(rd2, 31);
     }
#endif
}
Beispiel #12
0
void gensra()
{
#ifdef INTERPRET_SRA
   gencallinterp((unsigned long)SRA, 0);
#else
   int rt = allocate_register((unsigned long *)dst->f.r.rt);
   int rd = allocate_register_w((unsigned long *)dst->f.r.rd);
   
   mov_reg32_reg32(rd, rt);
   sar_reg32_imm8(rd, dst->f.r.sa);
#endif
}
Beispiel #13
0
void gendsra32()
{
#ifdef INTERPRET_DSRA32
   gencallinterp((unsigned long)DSRA32, 0);
#else
   int rt2 = allocate_64_register2((unsigned long *)dst->f.r.rt);
   int rd = allocate_register_w((unsigned long *)dst->f.r.rd);
   
   mov_reg32_reg32(rd, rt2);
   sar_reg32_imm8(rd, dst->f.r.sa);
#endif
}
Beispiel #14
0
void gensra(void)
{
#ifdef INTERPRET_SRA
    gencallinterp((unsigned int)cached_interpreter_table.SRA, 0);
#else
    int rt = allocate_register((unsigned int *)dst->f.r.rt);
    int rd = allocate_register_w((unsigned int *)dst->f.r.rd);

    mov_reg32_reg32(rd, rt);
    sar_reg32_imm8(rd, dst->f.r.sa);
#endif
}
Beispiel #15
0
void gendsra32(void)
{
#ifdef INTERPRET_DSRA32
    gencallinterp((unsigned int)cached_interpreter_table.DSRA32, 0);
#else
    int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
    int rd = allocate_register_w((unsigned int *)dst->f.r.rd);

    mov_reg32_reg32(rd, rt2);
    sar_reg32_imm8(rd, dst->f.r.sa);
#endif
}
Beispiel #16
0
void gencfc1(void)
{
#ifdef INTERPRET_CFC1
   gencallinterp((unsigned int)CFC1, 0);
#else
   gencheck_cop1_unusable();
   if(dst->f.r.nrd == 31) mov_eax_memoffs32((unsigned int*)&FCR31);
   else mov_eax_memoffs32((unsigned int*)&FCR0);
   mov_memoffs32_eax((unsigned int*)dst->f.r.rt);
   sar_reg32_imm8(EAX, 31);
   mov_memoffs32_eax(((unsigned int*)dst->f.r.rt)+1);
#endif
}
Beispiel #17
0
void genmfc1(void)
{
#ifdef INTERPRET_MFC1
   gencallinterp((unsigned int)MFC1, 0);
#else
   gencheck_cop1_unusable();
   mov_eax_memoffs32((unsigned int*)(&reg_cop1_simple[dst->f.r.nrd]));
   mov_reg32_preg32(EBX, EAX);
   mov_m32_reg32((unsigned int*)dst->f.r.rt, EBX);
   sar_reg32_imm8(EBX, 31);
   mov_m32_reg32(((unsigned int*)dst->f.r.rt)+1, EBX);
#endif
}
Beispiel #18
0
void gensra(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[57]);
#endif
#ifdef INTERPRET_SRA
   gencallinterp((unsigned long long)SRA, 0);
#else
   int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
   
   mov_reg32_reg32(rd, rt);
   sar_reg32_imm8(rd, dst->f.r.sa);
#endif
}
Beispiel #19
0
void gencfc1(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[113]);
#endif
#ifdef INTERPRET_CFC1
   gencallinterp((unsigned long long)cached_interpreter_table.CFC1, 0);
#else
   gencheck_cop1_unusable();
   if(dst->f.r.nrd == 31) mov_xreg32_m32rel(EAX, (unsigned int*)&FCR31);
   else mov_xreg32_m32rel(EAX, (unsigned int*)&FCR0);
   mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EAX);
   sar_reg32_imm8(EAX, 31);
   mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EAX);
#endif
}
Beispiel #20
0
void genmfc1(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[111]);
#endif
#ifdef INTERPRET_MFC1
   gencallinterp((unsigned long long)cached_interpreter_table.MFC1, 0);
#else
   gencheck_cop1_unusable();
   mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_cop1_simple[dst->f.r.nrd]));
   mov_reg32_preg64(EBX, RAX);
   mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EBX);
   sar_reg32_imm8(EBX, 31);
   mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EBX);
#endif
}
Beispiel #21
0
// this function is similar to allocate_register except it loads
// a 64 bits value, and return the register number of the MSB part
int allocate_64_register2(unsigned int *addr)
{
   int reg1, reg2, i;
   
   // is it already cached as a 32 bits value ?
   for (i=0; i<8; i++)
     {
    if (last_access[i] != NULL && reg_content[i] == addr)
      {
         if (r64[i] == -1)
           {
          allocate_register(addr);
          reg2 = allocate_register(dirty[i] ? NULL : addr+1);
          r64[i] = reg2;
          r64[reg2] = i;
          
          if (dirty[i])
            {
               reg_content[reg2] = addr+1;
               dirty[reg2] = 1;
               mov_reg32_reg32(reg2, i);
               sar_reg32_imm8(reg2, 31);
            }
          
          return reg2;
           }
      }
     }
   
   reg1 = allocate_register(addr);
   reg2 = allocate_register(addr+1);
   r64[reg1] = reg2;
   r64[reg2] = reg1;
   
   return reg2;
}
Beispiel #22
0
// this function is similar to allocate_register except it loads
// a 64 bits value, and return the register number of the LSB part
int allocate_64_register1(unsigned int *addr)
{
   int reg1, reg2, i;
   
   // is it already cached as a 32 bits value ?
   for (i=0; i<8; i++)
     {
    if (g_dev.r4300.regcache_state.last_access[i] != NULL && g_dev.r4300.regcache_state.reg_content[i] == addr)
      {
         if (g_dev.r4300.regcache_state.r64[i] == -1)
           {
          allocate_register(addr);
          reg2 = allocate_register(g_dev.r4300.regcache_state.dirty[i] ? NULL : addr+1);
          g_dev.r4300.regcache_state.r64[i] = reg2;
          g_dev.r4300.regcache_state.r64[reg2] = i;
          
          if (g_dev.r4300.regcache_state.dirty[i])
            {
               g_dev.r4300.regcache_state.reg_content[reg2] = addr+1;
               g_dev.r4300.regcache_state.dirty[reg2] = 1;
               mov_reg32_reg32(reg2, i);
               sar_reg32_imm8(reg2, 31);
            }
          
          return i;
           }
      }
     }
   
   reg1 = allocate_register(addr);
   reg2 = allocate_register(addr+1);
   g_dev.r4300.regcache_state.r64[reg1] = reg2;
   g_dev.r4300.regcache_state.r64[reg2] = reg1;
   
   return reg1;
}
Beispiel #23
0
// this function is similar to allocate_register except it loads
// a 64 bits value, and return the register number of the MSB part
int allocate_64_register2(usf_state_t * state, unsigned int *addr)
{
   int reg1, reg2, i;
   
   // is it already cached as a 32 bits value ?
   for (i=0; i<8; i++)
     {
    if (state->last_access[i] != NULL && state->reg_content[i] == addr)
      {
         if (state->r64[i] == -1)
           {
          allocate_register(state, addr);
          reg2 = allocate_register(state, state->dirty[i] ? NULL : addr+1);
          state->r64[i] = reg2;
          state->r64[reg2] = i;
          
          if (state->dirty[i])
            {
               state->reg_content[reg2] = addr+1;
               state->dirty[reg2] = 1;
               mov_reg32_reg32(state, reg2, i);
               sar_reg32_imm8(state, reg2, 31);
            }
          
          return reg2;
           }
      }
     }
   
   reg1 = allocate_register(state, addr);
   reg2 = allocate_register(state, addr+1);
   state->r64[reg1] = reg2;
   state->r64[reg2] = reg1;
   
   return reg2;
}
Beispiel #24
0
int allocate_64_register2_w(usf_state_t * state, unsigned int *addr)
{
   int reg1, reg2, i;
   
   // is it already cached as a 32 bits value ?
   for (i=0; i<8; i++)
     {
    if (state->last_access[i] != NULL && state->reg_content[i] == addr)
      {
         if (state->r64[i] == -1)
           {
          allocate_register_w(state, addr);
          reg2 = lru_register(state);
          if (state->last_access[reg2]) free_register(state, reg2);
          else
          {
            while (state->free_since[reg2] <= state->dst)
            {
              state->free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
              state->free_since[reg2]++;
            }
          }
          state->r64[i] = reg2;
          state->r64[reg2] = i;
          state->last_access[reg2] = state->dst;
          
          state->reg_content[reg2] = addr+1;
          state->dirty[reg2] = 1;
          mov_reg32_reg32(state, reg2, i);
          sar_reg32_imm8(state, reg2, 31);
          
          return reg2;
           }
         else
           {
          state->last_access[i] = state->dst;
          state->last_access[state->r64[i]] = state->dst;
          state->dirty[i] = state->dirty[state->r64[i]] = 1;
          return state->r64[i];
           }
      }
     }
   
   reg1 = allocate_register_w(state, addr);
   reg2 = lru_register(state);
   if (state->last_access[reg2]) free_register(state, reg2);
   else
     {
    while (state->free_since[reg2] <= state->dst)
      {
         state->free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
         state->free_since[reg2]++;
      }
     }
   state->r64[reg1] = reg2;
   state->r64[reg2] = reg1;
   state->last_access[reg2] = state->dst;
   state->reg_content[reg2] = addr+1;
   state->dirty[reg2] = 1;
   
   return reg2;
}
Beispiel #25
0
int allocate_64_register2_w(unsigned int *addr)
{
   int reg1, reg2, i;
   
   // is it already cached as a 32 bits value ?
   for (i=0; i<8; i++)
     {
    if (last_access[i] != NULL && reg_content[i] == addr)
      {
         if (r64[i] == -1)
           {
          allocate_register_w(addr);
          reg2 = lru_register();
          if (last_access[reg2]) free_register(reg2);
          else
          {
            while (free_since[reg2] <= dst)
            {
              free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
              free_since[reg2]++;
            }
          }
          r64[i] = reg2;
          r64[reg2] = i;
          last_access[reg2] = dst;
          
          reg_content[reg2] = addr+1;
          dirty[reg2] = 1;
          mov_reg32_reg32(reg2, i);
          sar_reg32_imm8(reg2, 31);
          
          return reg2;
           }
         else
           {
          last_access[i] = dst;
          last_access[r64[i]] = dst;
          dirty[i] = dirty[r64[i]] = 1;
          return r64[i];
           }
      }
     }
   
   reg1 = allocate_register_w(addr);
   reg2 = lru_register();
   if (last_access[reg2]) free_register(reg2);
   else
     {
    while (free_since[reg2] <= dst)
      {
         free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
         free_since[reg2]++;
      }
     }
   r64[reg1] = reg2;
   r64[reg2] = reg1;
   last_access[reg2] = dst;
   reg_content[reg2] = addr+1;
   dirty[reg2] = 1;
   
   return reg2;
}
Beispiel #26
0
int allocate_64_register2_w(unsigned int *addr)
{
   int reg1, reg2, i;
   
   // is it already cached as a 32 bits value ?
   for (i=0; i<8; i++)
     {
    if (g_dev.r4300.regcache_state.last_access[i] != NULL && g_dev.r4300.regcache_state.reg_content[i] == addr)
      {
         if (g_dev.r4300.regcache_state.r64[i] == -1)
           {
          allocate_register_w(addr);
          reg2 = lru_register();
          if (g_dev.r4300.regcache_state.last_access[reg2]) free_register(reg2);
          else
          {
            while (g_dev.r4300.regcache_state.free_since[reg2] <= g_dev.r4300.recomp.dst)
            {
              g_dev.r4300.regcache_state.free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
              g_dev.r4300.regcache_state.free_since[reg2]++;
            }
          }
          g_dev.r4300.regcache_state.r64[i] = reg2;
          g_dev.r4300.regcache_state.r64[reg2] = i;
          g_dev.r4300.regcache_state.last_access[reg2] = g_dev.r4300.recomp.dst;
          
          g_dev.r4300.regcache_state.reg_content[reg2] = addr+1;
          g_dev.r4300.regcache_state.dirty[reg2] = 1;
          mov_reg32_reg32(reg2, i);
          sar_reg32_imm8(reg2, 31);
          
          return reg2;
           }
         else
           {
          g_dev.r4300.regcache_state.last_access[i] = g_dev.r4300.recomp.dst;
          g_dev.r4300.regcache_state.last_access[g_dev.r4300.regcache_state.r64[i]] = g_dev.r4300.recomp.dst;
          g_dev.r4300.regcache_state.dirty[i] = g_dev.r4300.regcache_state.dirty[g_dev.r4300.regcache_state.r64[i]] = 1;
          return g_dev.r4300.regcache_state.r64[i];
           }
      }
     }
   
   reg1 = allocate_register_w(addr);
   reg2 = lru_register();
   if (g_dev.r4300.regcache_state.last_access[reg2]) free_register(reg2);
   else
     {
    while (g_dev.r4300.regcache_state.free_since[reg2] <= g_dev.r4300.recomp.dst)
      {
         g_dev.r4300.regcache_state.free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
         g_dev.r4300.regcache_state.free_since[reg2]++;
      }
     }
   g_dev.r4300.regcache_state.r64[reg1] = reg2;
   g_dev.r4300.regcache_state.r64[reg2] = reg1;
   g_dev.r4300.regcache_state.last_access[reg2] = g_dev.r4300.recomp.dst;
   g_dev.r4300.regcache_state.reg_content[reg2] = addr+1;
   g_dev.r4300.regcache_state.dirty[reg2] = 1;
   
   return reg2;
}