Example #1
0
void gensrav(void)
{
#ifdef INTERPRET_SRAV
    gencallinterp((unsigned int)cached_interpreter_table.SRAV, 0);
#else
    int rt, rd;
    allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);

    rt = allocate_register((unsigned int *)dst->f.r.rt);
    rd = allocate_register_w((unsigned int *)dst->f.r.rd);

    if (rd != ECX)
    {
        mov_reg32_reg32(rd, rt);
        sar_reg32_cl(rd);
    }
    else
    {
        int temp = lru_register();
        free_register(temp);
        mov_reg32_reg32(temp, rt);
        sar_reg32_cl(temp);
        mov_reg32_reg32(rd, temp);
    }
#endif
}
Example #2
0
static void genbranchlink(void)
{
   int r31_64bit = is64((unsigned int*)&reg[31]);
   
   if (!r31_64bit)
     {
    int r31 = allocate_register_w((unsigned int *)&reg[31]);
    
    mov_reg32_imm32(r31, dst->addr+8);
     }
   else if (r31_64bit == -1)
     {
    mov_m32_imm32((unsigned int *)&reg[31], dst->addr + 8);
    if (dst->addr & 0x80000000)
      mov_m32_imm32(((unsigned int *)&reg[31])+1, 0xFFFFFFFF);
    else
      mov_m32_imm32(((unsigned int *)&reg[31])+1, 0);
     }
   else
     {
    int r311 = allocate_64_register1_w((unsigned int *)&reg[31]);
    int r312 = allocate_64_register2_w((unsigned int *)&reg[31]);
    
    mov_reg32_imm32(r311, dst->addr+8);
    if (dst->addr & 0x80000000)
      mov_reg32_imm32(r312, 0xFFFFFFFF);
    else
      mov_reg32_imm32(r312, 0);
     }
}
Example #3
0
void gensllv(usf_state_t * state)
{
#ifdef INTERPRET_SLLV
   gencallinterp(state, (unsigned int)state->current_instruction_table.SLLV, 0);
#else
   int rt, rd;
   allocate_register_manually(state, ECX, (unsigned int *)state->dst->f.r.rs);
   
   rt = allocate_register(state, (unsigned int *)state->dst->f.r.rt);
   rd = allocate_register_w(state, (unsigned int *)state->dst->f.r.rd);
   
   if (rd != ECX)
     {
    mov_reg32_reg32(state, rd, rt);
    shl_reg32_cl(state, rd);
     }
   else
     {
    int temp = lru_register(state);
    free_register(state, temp);
    mov_reg32_reg32(state, temp, rt);
    shl_reg32_cl(state, temp);
    mov_reg32_reg32(state, rd, temp);
     }
#endif
}
Example #4
0
void gensllv()
{
#ifdef INTERPRET_SLLV
   gencallinterp((unsigned long)SLLV, 0);
#else
   int rt, rd;
   allocate_register_manually(ECX, (unsigned long *)dst->f.r.rs);
   
   rt = allocate_register((unsigned long *)dst->f.r.rt);
   rd = allocate_register_w((unsigned long *)dst->f.r.rd);
   
   if (rd != ECX)
     {
	mov_reg32_reg32(rd, rt);
	shl_reg32_cl(rd);
     }
   else
     {
	int temp = lru_register();
	free_register(temp);
	mov_reg32_reg32(temp, rt);
	shl_reg32_cl(temp);
	mov_reg32_reg32(rd, temp);
     }
#endif
}
Example #5
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
}
Example #6
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
}
Example #7
0
void gensrl(void)
{
#ifdef INTERPRET_SRL
   gencallinterp((unsigned int)cached_interpreter_table.SRL, 0);
#else
   int rt = allocate_register((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rd = allocate_register_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   
   mov_reg32_reg32(rd, rt);
   shr_reg32_imm8(rd, g_dev.r4300.recomp.dst->f.r.sa);
#endif
}
Example #8
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
}
Example #9
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
}
Example #10
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
}
Example #11
0
static void genbranchlink(void)
{
   int r31_64bit = is64((unsigned int*)&reg[31]);

   if (r31_64bit == 0)
   {
#ifdef __x86_64__
      int r31 = allocate_register_32_w((unsigned int *)&reg[31]);

      mov_reg32_imm32(r31, dst->addr+8);
#else
      int r31 = allocate_register_w((unsigned int *)&reg[31]);

      mov_reg32_imm32(r31, dst->addr+8);
#endif
   }
   else if (r31_64bit == -1)
   {
#ifdef __x86_64__
      mov_m32rel_imm32((unsigned int *)&reg[31], dst->addr + 8);
      if (dst->addr & 0x80000000)
         mov_m32rel_imm32(((unsigned int *)&reg[31])+1, 0xFFFFFFFF);
      else
         mov_m32rel_imm32(((unsigned int *)&reg[31])+1, 0);
#else
      mov_m32_imm32((unsigned int *)&reg[31], dst->addr + 8);
      if (dst->addr & 0x80000000)
         mov_m32_imm32(((unsigned int *)&reg[31])+1, 0xFFFFFFFF);
      else
         mov_m32_imm32(((unsigned int *)&reg[31])+1, 0);
#endif
   }
   else
   {
#ifdef __x86_64__
      int r31 = allocate_register_64_w((uint64_t*)&reg[31]);

      mov_reg32_imm32(r31, dst->addr+8);
      movsxd_reg64_reg32(r31, r31);
#else
      int r311 = allocate_64_register1_w((unsigned int *)&reg[31]);
      int r312 = allocate_64_register2_w((unsigned int *)&reg[31]);

      mov_reg32_imm32(r311, dst->addr+8);
      if (dst->addr & 0x80000000)
         mov_reg32_imm32(r312, 0xFFFFFFFF);
      else
         mov_reg32_imm32(r312, 0);
#endif
   }
}
Example #12
0
void gensltu()
{
#ifdef INTERPRET_SLTU
   gencallinterp((unsigned long)SLTU, 0);
#else
   int rs1 = allocate_64_register1((unsigned long *)dst->f.r.rs);
   int rs2 = allocate_64_register2((unsigned long *)dst->f.r.rs);
   int rt1 = allocate_64_register1((unsigned long *)dst->f.r.rt);
   int rt2 = allocate_64_register2((unsigned long *)dst->f.r.rt);
   int rd = allocate_register_w((unsigned long *)dst->f.r.rd);
   
   cmp_reg32_reg32(rs2, rt2);
   jb_rj(13);
   jne_rj(4); // 2
   cmp_reg32_reg32(rs1, rt1); // 2
   jb_rj(7); // 2
   mov_reg32_imm32(rd, 0); // 5
   jmp_imm_short(5); // 2
   mov_reg32_imm32(rd, 1); // 5
#endif
}
Example #13
0
void genslt(void)
{
#ifdef INTERPRET_SLT
    gencallinterp((unsigned int)cached_interpreter_table.SLT, 0);
#else
    int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
    int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
    int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
    int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
    int rd = allocate_register_w((unsigned int *)dst->f.r.rd);

    cmp_reg32_reg32(rs2, rt2);
    jl_rj(13);
    jne_rj(4); // 2
    cmp_reg32_reg32(rs1, rt1); // 2
    jl_rj(7); // 2
    mov_reg32_imm32(rd, 0); // 5
    jmp_imm_short(5); // 2
    mov_reg32_imm32(rd, 1); // 5
#endif
}
Example #14
0
void gensltu(usf_state_t * state)
{
#ifdef INTERPRET_SLTU
   gencallinterp(state, (unsigned int)state->current_instruction_table.SLTU, 0);
#else
   int rs1 = allocate_64_register1(state, (unsigned int *)state->dst->f.r.rs);
   int rs2 = allocate_64_register2(state, (unsigned int *)state->dst->f.r.rs);
   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 rd = allocate_register_w(state, (unsigned int *)state->dst->f.r.rd);
   
   cmp_reg32_reg32(state, rs2, rt2);
   jb_rj(state, 13);
   jne_rj(state, 4); // 2
   cmp_reg32_reg32(state, rs1, rt1); // 2
   jb_rj(state, 7); // 2
   mov_reg32_imm32(state, rd, 0); // 5
   jmp_imm_short(state, 5); // 2
   mov_reg32_imm32(state, rd, 1); // 5
#endif
}
Example #15
0
void gensubu()
{
#ifdef INTERPRET_SUBU
   gencallinterp((unsigned long)SUBU, 0);
#else
   int rs = allocate_register((unsigned long *)dst->f.r.rs);
   int rt = allocate_register((unsigned long *)dst->f.r.rt);
   int rd = allocate_register_w((unsigned long *)dst->f.r.rd);
   
   if (rt != rd && rs != rd)
     {
	mov_reg32_reg32(rd, rs);
	sub_reg32_reg32(rd, rt);
     }
   else
     {
	int temp = lru_register();
	free_register(temp);
	mov_reg32_reg32(temp, rs);
	sub_reg32_reg32(temp, rt);
	mov_reg32_reg32(rd, temp);
     }
#endif
}
Example #16
0
void gensub(void)
{
#ifdef INTERPRET_SUB
    gencallinterp((unsigned int)cached_interpreter_table.SUB, 0);
#else
    int rs = allocate_register((unsigned int *)dst->f.r.rs);
    int rt = allocate_register((unsigned int *)dst->f.r.rt);
    int rd = allocate_register_w((unsigned int *)dst->f.r.rd);

    if (rt != rd && rs != rd)
    {
        mov_reg32_reg32(rd, rs);
        sub_reg32_reg32(rd, rt);
    }
    else
    {
        int temp = lru_register();
        free_register(temp);
        mov_reg32_reg32(temp, rs);
        sub_reg32_reg32(temp, rt);
        mov_reg32_reg32(rd, temp);
    }
#endif
}
Example #17
0
void genaddu(void)
{
#ifdef INTERPRET_ADDU
   gencallinterp((unsigned int)cached_interpreter_table.ADDU, 0);
#else
   int rs = allocate_register((unsigned int *)g_dev.r4300.recomp.dst->f.r.rs);
   int rt = allocate_register((unsigned int *)g_dev.r4300.recomp.dst->f.r.rt);
   int rd = allocate_register_w((unsigned int *)g_dev.r4300.recomp.dst->f.r.rd);
   
   if (rt != rd && rs != rd)
     {
    mov_reg32_reg32(rd, rs);
    add_reg32_reg32(rd, rt);
     }
   else
     {
    int temp = lru_register();
    free_register(temp);
    mov_reg32_reg32(temp, rs);
    add_reg32_reg32(temp, rt);
    mov_reg32_reg32(rd, temp);
     }
#endif
}
Example #18
0
void gensubu(usf_state_t * state)
{
#ifdef INTERPRET_SUBU
   gencallinterp(state, (unsigned int)state->current_instruction_table.SUBU, 0);
#else
   int rs = allocate_register(state, (unsigned int *)state->dst->f.r.rs);
   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);
   
   if (rt != rd && rs != rd)
     {
    mov_reg32_reg32(state, rd, rs);
    sub_reg32_reg32(state, rd, rt);
     }
   else
     {
    int temp = lru_register(state);
    free_register(state, temp);
    mov_reg32_reg32(state, temp, rs);
    sub_reg32_reg32(state, temp, rt);
    mov_reg32_reg32(state, rd, temp);
     }
#endif
}
Example #19
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;
}
Example #20
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;
}
Example #21
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;
}