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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 } }
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 }
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 }
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 }
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 }
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); } }