コード例 #1
0
ファイル: gregimm.c プロジェクト: CatalystG/Mupen64Plus-PB
static void genbranchlink(void)
{
   int r31_64bit = is64((unsigned int*)&reg[31]);
   
   if (r31_64bit == 0)
     {
    int r31 = allocate_register_32_w((unsigned int *)&reg[31]);
    
    mov_reg32_imm32(r31, dst->addr+8);
     }
   else if (r31_64bit == -1)
     {
    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
     {
    int r31 = allocate_register_64_w((unsigned long long *)&reg[31]);
    
    mov_reg32_imm32(r31, dst->addr+8);
    movsxd_reg64_reg32(r31, r31);
     }
}
コード例 #2
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_register_64(unsigned long long *addr)
{
  int reg, i;

  // is it already cached?
  if (addr != NULL)
  {
    for (i = 0; i < 8; i++)
    {
      if (last_access[i] != NULL && reg_content[i] == addr)
      {
        precomp_instr *last = last_access[i]+1;

        while (last <= dst)
        {
          last->reg_cache_infos.needed_registers[i] = reg_content[i];
          last++;
        }
        last_access[i] = dst;
        if (is64bits[i] == 0)
        {
          movsxd_reg64_reg32(i, i);
          is64bits[i] = 1;
        }
        return i;
      }
    }
  }

  // it's not cached, so take the least recently used register
  reg = lru_register();
   
  if (last_access[reg])
    free_register(reg);
  else
  {
    while (free_since[reg] <= dst)
    {
      free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
      free_since[reg]++;
    }
  }
   
  last_access[reg] = dst;
  reg_content[reg] = addr;
  dirty[reg] = 0;
  is64bits[reg] = 1;
   
  if (addr != NULL)
  {
    if (addr == r0)
      xor_reg64_reg64(reg, reg);
    else
      mov_xreg64_m64rel(reg, addr);
  }

  return reg;
}
コード例 #3
0
ファイル: regcache.c プロジェクト: derselbst/lazyusf2
// 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_register_64(usf_state_t * state, unsigned long long *addr)
{
  int reg, i;

  // is it already cached?
  if (addr != NULL)
  {
    for (i = 0; i < 8; i++)
    {
      if (state->last_access[i] != NULL && state->reg_content[i] == addr)
      {
        precomp_instr *last = state->last_access[i]+1;

        while (last <= state->dst)
        {
          last->reg_cache_infos.needed_registers[i] = state->reg_content[i];
          last++;
        }
        state->last_access[i] = state->dst;
        if (state->is64bits[i] == 0)
        {
          movsxd_reg64_reg32(state, i, i);
          state->is64bits[i] = 1;
        }
        return i;
      }
    }
  }

  // it's not cached, so take the least recently used register
  reg = lru_register(state);
   
  if (state->last_access[reg])
    free_register(state, reg);
  else
  {
    while (state->free_since[reg] <= state->dst)
    {
      state->free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
      state->free_since[reg]++;
    }
  }
   
  state->last_access[reg] = state->dst;
  state->reg_content[reg] = addr;
  state->dirty[reg] = 0;
  state->is64bits[reg] = 1;
   
  if (addr != NULL)
  {
    if (addr == state->r0)
      xor_reg64_reg64(state, reg, reg);
    else
      mov_xreg64_m64rel(state, reg, addr);
  }

  return reg;
}
コード例 #4
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
   }
}
コード例 #5
0
ファイル: regcache.c プロジェクト: derselbst/lazyusf2
// this function frees a specific X86 GPR
void free_register(usf_state_t * state, int reg)
{
  precomp_instr *last;
  
  if (state->last_access[reg] == (precomp_instr *) 0xFFFFFFFFFFFFFFFFULL)
    unlock_register(state, reg);

  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;
    last++;
  }
  if (state->last_access[reg] == NULL)
  {
    state->free_since[reg] = state->dst+1;
    return;
  }

  if (state->dirty[reg])
  {
    if (state->is64bits[reg])
    {
      mov_m64rel_xreg64(state, (unsigned long long *) state->reg_content[reg], reg);
    }
    else
    {
      movsxd_reg64_reg32(state, reg, reg);
      mov_m64rel_xreg64(state, (unsigned long long *) state->reg_content[reg], reg);
    }
  }

  state->last_access[reg] = NULL;
  state->free_since[reg] = state->dst+1;
}
コード例 #6
0
// this function frees a specific X86 GPR
void free_register(int reg)
{
  precomp_instr *last;
   
  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;
    last++;
  }
  if (last_access[reg] == NULL) 
  {
    free_since[reg] = dst+1;
    return;
  }

  if (dirty[reg]) 
  {
    if (is64bits[reg])
    {
      mov_m64rel_xreg64((unsigned long long *) reg_content[reg], reg);
    }
    else
    {
      movsxd_reg64_reg32(reg, reg);
      mov_m64rel_xreg64((unsigned long long *) reg_content[reg], reg);
    }
  }

  last_access[reg] = NULL;
  free_since[reg] = dst+1;
}