void gendsllv(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[68]); #endif #ifdef INTERPRET_DSLLV gencallinterp((unsigned long long)cached_interpreter_table.DSLLV, 0); #else int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_64((unsigned long long *)dst->f.r.rt); rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rd != ECX) { mov_reg64_reg64(rd, rt); shl_reg64_cl(rd); } else { int temp; temp = lru_register(); free_register(temp); mov_reg64_reg64(temp, rt); shl_reg64_cl(temp); mov_reg64_reg64(rd, temp); } #endif }
static void genbranchlink(void) { int r31_64bit = is64((unsigned int*)®[31]); if (r31_64bit == 0) { int r31 = allocate_register_32_w((unsigned int *)®[31]); mov_reg32_imm32(r31, dst->addr+8); } else if (r31_64bit == -1) { mov_m32rel_imm32((unsigned int *)®[31], dst->addr + 8); if (dst->addr & 0x80000000) mov_m32rel_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF); else mov_m32rel_imm32(((unsigned int *)®[31])+1, 0); } else { int r31 = allocate_register_64_w((unsigned long long *)®[31]); mov_reg32_imm32(r31, dst->addr+8); movsxd_reg64_reg32(r31, r31); } }
void gendsubu(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[92]); #endif #ifdef INTERPRET_DSUBU gencallinterp((unsigned long long)DSUBU, 0); #else int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rs == rd) sub_reg64_reg64(rd, rt); else if (rt == rd) { neg_reg64(rd); add_reg64_reg64(rd, rs); } else { mov_reg64_reg64(rd, rs); sub_reg64_reg64(rd, rt); } #endif }
void gennor(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[86]); #endif #ifdef INTERPRET_NOR gencallinterp((unsigned long long)NOR, 0); #else int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rs == rd) { or_reg64_reg64(rd, rt); not_reg64(rd); } else if (rt == rd) { or_reg64_reg64(rd, rs); not_reg64(rd); } else { mov_reg64_reg64(rd, rs); or_reg64_reg64(rd, rt); not_reg64(rd); } #endif }
void gendsrav(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[70]); #endif #ifdef INTERPRET_DSRAV gencallinterp((unsigned long long)DSRAV, 0); #else int rt, rd; allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs); rt = allocate_register_64((unsigned long long *)dst->f.r.rt); rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rd != ECX) { mov_reg64_reg64(rd, rt); sar_reg64_cl(rd); } else { int temp; temp = lru_register(); free_register(temp); mov_reg64_reg64(temp, rt); sar_reg64_cl(temp); mov_reg64_reg64(rd, temp); } #endif }
static void genbranchlink(void) { int r31_64bit = is64((unsigned int*)®[31]); if (r31_64bit == 0) { #ifdef __x86_64__ int r31 = allocate_register_32_w((unsigned int *)®[31]); mov_reg32_imm32(r31, dst->addr+8); #else int r31 = allocate_register_w((unsigned int *)®[31]); mov_reg32_imm32(r31, dst->addr+8); #endif } else if (r31_64bit == -1) { #ifdef __x86_64__ mov_m32rel_imm32((unsigned int *)®[31], dst->addr + 8); if (dst->addr & 0x80000000) mov_m32rel_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF); else mov_m32rel_imm32(((unsigned int *)®[31])+1, 0); #else mov_m32_imm32((unsigned int *)®[31], dst->addr + 8); if (dst->addr & 0x80000000) mov_m32_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF); else mov_m32_imm32(((unsigned int *)®[31])+1, 0); #endif } else { #ifdef __x86_64__ int r31 = allocate_register_64_w((uint64_t*)®[31]); mov_reg32_imm32(r31, dst->addr+8); movsxd_reg64_reg32(r31, r31); #else int r311 = allocate_64_register1_w((unsigned int *)®[31]); int r312 = allocate_64_register2_w((unsigned int *)®[31]); mov_reg32_imm32(r311, dst->addr+8); if (dst->addr & 0x80000000) mov_reg32_imm32(r312, 0xFFFFFFFF); else mov_reg32_imm32(r312, 0); #endif } }
void genmtlo(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[67]); #endif #ifdef INTERPRET_MTLO gencallinterp((unsigned long long)MTLO, 0); #else int _lo = allocate_register_64_w((unsigned long long *)&lo); int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); mov_reg64_reg64(_lo, rs); #endif }
void genmthi(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[65]); #endif #ifdef INTERPRET_MTHI gencallinterp((unsigned long long)MTHI, 0); #else int _hi = allocate_register_64_w((unsigned long long *) &hi); int rs = allocate_register_64((unsigned long long *) dst->f.r.rs); mov_reg64_reg64(_hi, rs); #endif }
void genmflo(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[66]); #endif #ifdef INTERPRET_MFLO gencallinterp((unsigned long long)cached_interpreter_table.MFLO, 0); #else int rd = allocate_register_64_w((unsigned long long *) dst->f.r.rd); int _lo = allocate_register_64((unsigned long long *) &lo); mov_reg64_reg64(rd, _lo); #endif }
void gendsra(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[95]); #endif #ifdef INTERPRET_DSRA gencallinterp((unsigned long long)DSRA, 0); #else int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); mov_reg64_reg64(rd, rt); sar_reg64_imm8(rd, dst->f.r.sa); #endif }
void gendsrl(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[94]); #endif #ifdef INTERPRET_DSRL gencallinterp((unsigned long long)cached_interpreter_table.DSRL, 0); #else int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); mov_reg64_reg64(rd, rt); shr_reg64_imm8(rd, dst->f.r.sa); #endif }
void gensltu(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[88]); #endif #ifdef INTERPRET_SLTU gencallinterp((unsigned long long)SLTU, 0); #else int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); cmp_reg64_reg64(rs, rt); setb_reg8(rd); and_reg64_imm8(rd, 1); #endif }
void genslt(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[87]); #endif #ifdef INTERPRET_SLT gencallinterp((unsigned long long)cached_interpreter_table.SLT, 0); #else int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); cmp_reg64_reg64(rs, rt); setl_reg8(rd); and_reg64_imm8(rd, 1); #endif }
void genand(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[83]); #endif #ifdef INTERPRET_AND gencallinterp((unsigned long long)AND, 0); #else int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rs == rd) and_reg64_reg64(rd, rt); else if (rt == rd) and_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); and_reg64_reg64(rd, rt); } #endif }
void gendaddu(void) { #if defined(COUNT_INSTR) inc_m32rel(&instr_count[90]); #endif #ifdef INTERPRET_DADDU gencallinterp((unsigned long long)cached_interpreter_table.DADDU, 0); #else int rs = allocate_register_64((unsigned long long *)dst->f.r.rs); int rt = allocate_register_64((unsigned long long *)dst->f.r.rt); int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd); if (rs == rd) add_reg64_reg64(rd, rt); else if (rt == rd) add_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); add_reg64_reg64(rd, rt); } #endif }