예제 #1
0
void gensubu(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[82]);
#endif
#ifdef INTERPRET_SUBU
   gencallinterp((unsigned long long)SUBU, 0);
#else
   int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
   int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);

   if (rs == rd)
     sub_reg32_reg32(rd, rt);
   else if (rt == rd)
   {
     neg_reg32(rd);
     add_reg32_reg32(rd, rs);
   }
   else
     {
    mov_reg32_reg32(rd, rs);
    sub_reg32_reg32(rd, rt);
     }
#endif
}
예제 #2
0
void gensllv(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[58]);
#endif
#ifdef INTERPRET_SLLV
   gencallinterp((unsigned long long)SLLV, 0);
#else
   int rt, rd;
   allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
   
   rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   rd = allocate_register_32_w((unsigned int *)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
}
예제 #3
0
void gensrav(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[60]);
#endif
#ifdef INTERPRET_SRAV
   gencallinterp((unsigned long long)cached_interpreter_table.SRAV, 0);
#else
   int rt, rd;
   allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
   
   rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   rd = allocate_register_32_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
}
예제 #4
0
void genmultu(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[72]);
#endif
#ifdef INTERPRET_MULTU
   gencallinterp((unsigned long long)MULTU, 0);
#else
   int rs, rt;
   allocate_register_32_manually_w(EAX, (unsigned int *)&lo);
   allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
   rs = allocate_register_32((unsigned int*)dst->f.r.rs);
   rt = allocate_register_32((unsigned int*)dst->f.r.rt);
   mov_reg32_reg32(EAX, rs);
   mul_reg32(rt);
#endif
}
예제 #5
0
void genmult(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[71]);
#endif
#ifdef INTERPRET_MULT
   gencallinterp((unsigned long long)MULT, 0);
#else
   int rs, rt;
   allocate_register_32_manually_w(EAX, (unsigned int *)&lo); /* these must be done first so they are not assigned by allocate_register() */
   allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
   rs = allocate_register_32((unsigned int*)dst->f.r.rs);
   rt = allocate_register_32((unsigned int*)dst->f.r.rt);
   mov_reg32_reg32(EAX, rs);
   imul_reg32(rt);
#endif
}
예제 #6
0
void gendivu(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[74]);
#endif
#ifdef INTERPRET_DIVU
   gencallinterp((unsigned long long)DIVU, 0);
#else
   int rs, rt;
   allocate_register_32_manually_w(EAX, (unsigned int *)&lo);
   allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
   rs = allocate_register_32((unsigned int*)dst->f.r.rs);
   rt = allocate_register_32((unsigned int*)dst->f.r.rt);
   cmp_reg32_imm32(rt, 0);
   je_rj((rs == EAX ? 0 : 2) + 2 + 2);
   mov_reg32_reg32(EAX, rs); // 0 or 2
   xor_reg32_reg32(EDX, EDX); // 2
   div_reg32(rt); // 2
#endif
}
예제 #7
0
void gendiv(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[73]);
#endif
#ifdef INTERPRET_DIV
   gencallinterp((unsigned long long)cached_interpreter_table.DIV, 0);
#else
   int rs, rt;
   allocate_register_32_manually_w(EAX, (unsigned int *)&lo);
   allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
   rs = allocate_register_32((unsigned int*)dst->f.r.rs);
   rt = allocate_register_32((unsigned int*)dst->f.r.rt);
   cmp_reg32_imm32(rt, 0);
   je_rj((rs == EAX ? 0 : 2) + 1 + 2);
   mov_reg32_reg32(EAX, rs); // 0 or 2
   cdq(); // 1
   idiv_reg32(rt); // 2
#endif
}
예제 #8
0
static void genbltz_test(void)
{
   int rs_64bit = is64((unsigned int *)dst->f.i.rs);

   if (rs_64bit == 0)
   {
#ifdef __x86_64__
      int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
#else
      int rs = allocate_register((unsigned int *)dst->f.i.rs);
#endif

      cmp_reg32_imm32(rs, 0);
#ifdef __x86_64__
      setl_m8rel((unsigned char *) &branch_taken);
#else
      jge_rj(12);
      mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
      jmp_imm_short(10); // 2
      mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
#endif
   }
   else if (rs_64bit == -1)
   {
#ifdef __x86_64__
      cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
      setl_m8rel((unsigned char *) &branch_taken);
#else
      cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
      jge_rj(12);
      mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
      jmp_imm_short(10); // 2
      mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
#endif
   }
   else
   {
#ifdef __x86_64__
      int rs = allocate_register_64((uint64_t*)dst->f.i.rs);

      cmp_reg64_imm8(rs, 0);
      setl_m8rel((unsigned char *) &branch_taken);
#else
      int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);

      cmp_reg32_imm32(rs2, 0);
      jge_rj(12);
      mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
      jmp_imm_short(10); // 2
      mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
#endif
   }
}
예제 #9
0
void genadd(void)
{
#if defined(COUNT_INSTR)
   inc_m32abs(&instr_count[79]);
#endif
#ifdef INTERPRET_ADD
   gencallinterp((unsigned long long)ADD, 0);
#else
   int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
   int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);

   if (rs == rd)
     add_reg32_reg32(rd, rt);
   else if (rt == rd)
     add_reg32_reg32(rd, rs);
   else
     {
    mov_reg32_reg32(rd, rs);
    add_reg32_reg32(rd, rt);
     }
#endif
}
예제 #10
0
void genaddu(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[80]);
#endif
#ifdef INTERPRET_ADDU
   gencallinterp((unsigned long long)cached_interpreter_table.ADDU, 0);
#else
   int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
   int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
   int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);

   if (rs == rd)
     add_reg32_reg32(rd, rt);
   else if (rt == rd)
     add_reg32_reg32(rd, rs);
   else
     {
    mov_reg32_reg32(rd, rs);
    add_reg32_reg32(rd, rt);
     }
#endif
}
예제 #11
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
}
예제 #12
0
void gensrl(void)
{
#if defined(COUNT_INSTR)
   inc_m32rel(&instr_count[56]);
#endif
#ifdef INTERPRET_SRL
   gencallinterp((unsigned long long)cached_interpreter_table.SRL, 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);
   shr_reg32_imm8(rd, dst->f.r.sa);
#endif
}
예제 #13
0
void genbgez_test(void)
{
  int rs_64bit = is64((unsigned int *)dst->f.i.rs);
   
  if (rs_64bit == 0)
  {
    int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
    cmp_reg32_imm32(rs, 0);
    setge_m8rel((unsigned char *) &branch_taken);
  }
  else if (rs_64bit == -1)
  {
    cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
    setge_m8rel((unsigned char *) &branch_taken);
  }
  else
  {
    int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
    cmp_reg64_imm8(rs, 0);
    setge_m8rel((unsigned char *) &branch_taken);
  }
}