示例#1
0
void gendmultu(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[76]);
#endif
#ifdef INTERPRET_DMULTU
   gencallinterp((unsigned long long)cached_interpreter_table.DMULTU, 0);
#else
   free_registers_move_start();
   
   mov_xreg64_m64rel(RAX, (unsigned long long *) dst->f.r.rs);
   mov_xreg64_m64rel(RDX, (unsigned long long *) dst->f.r.rt);
   mul_reg64(RDX);
   mov_m64rel_xreg64((unsigned long long *) &lo, RAX);
   mov_m64rel_xreg64((unsigned long long *) &hi, RDX);
#endif
}
示例#2
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] == (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;
}
示例#3
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;
}
示例#4
0
void genjalr(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[62]);
#endif
#ifdef INTERPRET_JALR
   gencallinterp((unsigned long long)cached_interpreter_table.JALR, 0);
#else
   static unsigned int precomp_instr_size = sizeof(precomp_instr);
   unsigned int diff = (unsigned int) offsetof(precomp_instr, local_addr);
   unsigned int diff_need = (unsigned int) offsetof(precomp_instr, reg_cache_infos.need_map);
   unsigned int diff_wrap = (unsigned int) offsetof(precomp_instr, reg_cache_infos.jump_wrapper);
   
   if (((dst->addr & 0xFFF) == 0xFFC && 
       (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
     {
    gencallinterp((unsigned long long)cached_interpreter_table.JALR, 1);
    return;
     }
   
   free_registers_move_start();

   mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.r.rs);
   mov_m32rel_xreg32((unsigned int *)&local_rs, EAX);
   
   gendelayslot();
   
   mov_m32rel_imm32((unsigned int *)(dst-1)->f.r.rd, dst->addr+4);
   if ((dst->addr+4) & 0x80000000)
     mov_m32rel_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF);
   else
     mov_m32rel_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0);
   
   mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs);
   mov_m32rel_xreg32((unsigned int *)&last_addr, EAX);
   
   gencheck_interupt_reg();
   
   mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs);
   mov_reg32_reg32(EBX, EAX);
   and_eax_imm32(0xFFFFF000);
   cmp_eax_imm32(dst_block->start & 0xFFFFF000);
   je_near_rj(0);

   jump_start_rel32();
   
   mov_m32rel_xreg32(&jump_to_address, EBX);
   mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
   mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
   mov_reg64_imm64(RAX, (unsigned long long) jump_to_func);
   call_reg64(RAX);  /* will never return from call */

   jump_end_rel32();

   mov_reg64_imm64(RSI, (unsigned long long) dst_block->block);
   mov_reg32_reg32(EAX, EBX);
   sub_eax_imm32(dst_block->start);
   shr_reg32_imm8(EAX, 2);
   mul_m32rel((unsigned int *)(&precomp_instr_size));

   mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff_need);
   cmp_reg32_imm32(EBX, 1);
   jne_rj(11);

   add_reg32_imm32(EAX, diff_wrap); // 6
   add_reg64_reg64(RAX, RSI); // 3
   jmp_reg64(RAX); // 2

   mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff);
   mov_rax_memoffs64((unsigned long long *) &dst_block->code);
   add_reg64_reg64(RAX, RBX);
   jmp_reg64(RAX);
#endif
}