// 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; }
// 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; }
void genxor(void) { #if defined(COUNT_INSTR) inc_m32abs(&instr_count[85]); #endif #ifdef INTERPRET_XOR gencallinterp((unsigned long long)XOR, 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) xor_reg64_reg64(rd, rt); else if (rt == rd) xor_reg64_reg64(rd, rs); else { mov_reg64_reg64(rd, rs); xor_reg64_reg64(rd, rt); } #endif }