Example #1
0
int mapFPR(int fpr, int dbl){
	PowerPC_instr ppc;
	
	fprMap[fpr].lru = nextLRUValFPR++;
	fprMap[fpr].dbl = dbl; // Set whether this is a double-precision
	
	// If its already been mapped, just return that value
	// FIXME: Do I need to worry about conversions between single and double?
	if(fprMap[fpr].map >= 0) return fprMap[fpr].map;
	
	fprMap[fpr].dirty = 0; // If it hasn't previously been mapped, its clean
	// Try to find any already available register
	fprMap[fpr].map = getAvailableFPR();
	// If didn't find an available register, flush one
	if(fprMap[fpr].map < 0) fprMap[fpr].map = flushLRUFPR();
	
	// Load the register from memory (indirectly)
	if(dbl){
		GEN_LWZ(ppc, R0, SDAREL(reg_cop1_double) + fpr*4, R13);
		set_next_dst(ppc);
		GEN_LFDX(ppc, fprMap[fpr].map, 0, R0);
		set_next_dst(ppc);
	} else {
		GEN_LWZ(ppc, R0, SDAREL(reg_cop1_simple) + fpr*4, R13);
		set_next_dst(ppc);
		GEN_LFSX(ppc, fprMap[fpr].map, 0, R0);
		set_next_dst(ppc);
	}
	
	return fprMap[fpr].map;
}
Example #2
0
int mapRegister(int gpr){
	PowerPC_instr ppc;
	if(!gpr) return DYNAREG_ZERO; // Return r0 mapped to r31
	regMap[gpr].lru = nextLRUVal++;
	// If its already been mapped, just return that value
	if(regMap[gpr].map.lo >= 0){
		// Note: We don't want to free any 64-bit mapping that may exist
		//       because this may be a read-after-64-bit-write
		return regMap[gpr].map.lo;
	}
	regMap[gpr].dirty = 0; // If it hasn't previously been mapped, its clean
	// Iterate over the HW registers and find one that's available
	int available = getAvailableHWReg();
	if(available >= 0){
		GEN_LWZ(ppc, available, SDAREL(reg) + gpr*8+4, R13);
		set_next_dst(ppc);
		
		return regMap[gpr].map.lo = available;
	}
	// We didn't find an available register, so flush one
	RegMapping lru = flushLRURegister();
	if(lru.hi >= 0) availableRegs[lru.hi] = 1;
	// And load the registers value to the register we flushed
	GEN_LWZ(ppc, lru.lo, SDAREL(reg) + gpr*8+4, R13);
	set_next_dst(ppc);
	
	return regMap[gpr].map.lo = lru.lo;
}
Example #3
0
RegMapping mapRegister64(int gpr){
	PowerPC_instr ppc;
	if(!gpr) return (RegMapping){ DYNAREG_ZERO, DYNAREG_ZERO };
	regMap[gpr].lru = nextLRUVal++;
	// If its already been mapped, just return that value
	if(regMap[gpr].map.lo >= 0){
		// If the hi value is not mapped, find a mapping
		if(regMap[gpr].map.hi < 0){
			// Try to find any already available register
			int available = getAvailableHWReg();
			if(available >= 0){
				regMap[gpr].map.hi = available;
			} else {
				// We didn't find an available register, so flush one
				RegMapping lru = flushLRURegister();
				if(lru.hi >= 0) availableRegs[lru.hi] = 1;
				regMap[gpr].map.hi = lru.lo;
			}
			if(regMap[gpr].sign){
				// Sign extend to 64-bits
				GEN_SRAWI(ppc, regMap[gpr].map.hi, regMap[gpr].map.lo, 31);
				set_next_dst(ppc);
			} else {
				GEN_LI(ppc, regMap[gpr].map.hi, 0);
				set_next_dst(ppc);
			}
		}
		// Return the mapping
		return regMap[gpr].map;
	}
	regMap[gpr].dirty = 0; // If it hasn't previously been mapped, its clean
	
	// Try to find any already available registers
	regMap[gpr].map.hi = getAvailableHWReg();
	regMap[gpr].map.lo = getAvailableHWReg();
	// If there weren't enough registers, we'll have to flush
	if(regMap[gpr].map.lo < 0){
		// We didn't find any available registers, so flush one
		RegMapping lru = flushLRURegister();
		if(lru.hi >= 0) regMap[gpr].map.hi = lru.hi;
		regMap[gpr].map.lo = lru.lo;
	}
	if(regMap[gpr].map.hi < 0){
		// We didn't find an available register, so flush one
		RegMapping lru = flushLRURegister();
		if(lru.hi >= 0) availableRegs[lru.hi] = 1;
		regMap[gpr].map.hi = lru.lo;
	}
	// Load the values into the registers
	GEN_LWZ(ppc, regMap[gpr].map.hi, SDAREL(reg) + gpr*8, R13);
	set_next_dst(ppc);
	GEN_LWZ(ppc, regMap[gpr].map.lo, SDAREL(reg) + gpr*8+4, R13);
	set_next_dst(ppc);
	// Return the mapping
	return regMap[gpr].map;
}
Example #4
0
// Actually perform the store for a dirty register mapping
static void _flushFPR(int fpr){
	PowerPC_instr ppc;
	// Store the register to memory (indirectly)
	if(fprMap[fpr].dbl){
		GEN_LWZ(ppc, R0, SDAREL(reg_cop1_double) + fpr*4, R13);
		set_next_dst(ppc);
		GEN_STFDX(ppc, fprMap[fpr].map, 0, R0);
		set_next_dst(ppc);
	} else {
		GEN_LWZ(ppc, R0, SDAREL(reg_cop1_simple) + fpr*4, R13);
		set_next_dst(ppc);
		GEN_STFSX(ppc, fprMap[fpr].map, 0, R0);
		set_next_dst(ppc);
	}
}
// Actually perform the store for a dirty register mapping
static void _flushFPR(int reg){
	PowerPC_instr ppc;
	// Store the register to memory (indirectly)
	int addr = mapRegisterTemp();
	
	if(fprMap[reg].dbl){
		GEN_LWZ(ppc, addr, reg*4, DYNAREG_FPR_64);
		set_next_dst(ppc);
		GEN_STFD(ppc, fprMap[reg].map, 0, addr);
		set_next_dst(ppc);
	} else {
		GEN_LWZ(ppc, addr, reg*4, DYNAREG_FPR_32);
		set_next_dst(ppc);
		GEN_STFS(ppc, fprMap[reg].map, 0, addr);
		set_next_dst(ppc);
	}
	
	unmapRegisterTemp(addr);
}