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; }
// Actually perform the store for a dirty register mapping static void _flushRegister(int reg){ PowerPC_instr ppc; if(regMap[reg].map.hi >= 0){ // Simply store the mapped MSW GEN_STW(ppc, regMap[reg].map.hi, reg*8, DYNAREG_REG); set_next_dst(ppc); } else { // Sign extend to 64-bits GEN_SRAWI(ppc, 0, regMap[reg].map.lo, 31); set_next_dst(ppc); // Store the MSW GEN_STW(ppc, 0, reg*8, DYNAREG_REG); set_next_dst(ppc); } // Store the LSW GEN_STW(ppc, regMap[reg].map.lo, reg*8+4, DYNAREG_REG); set_next_dst(ppc); }
// Actually perform the store for a dirty register mapping static void _flushRegister(int gpr){ PowerPC_instr ppc; // Store the LSW GEN_STW(ppc, regMap[gpr].map.lo, SDAREL(reg) + gpr*8+4, R13); set_next_dst(ppc); if(regMap[gpr].map.hi >= 0){ // Simply store the mapped MSW GEN_STW(ppc, regMap[gpr].map.hi, SDAREL(reg) + gpr*8, R13); set_next_dst(ppc); } else if(regMap[gpr].sign){ // Sign extend to 64-bits GEN_SRAWI(ppc, R0, regMap[gpr].map.lo, 31); set_next_dst(ppc); // Store the MSW GEN_STW(ppc, R0, SDAREL(reg) + gpr*8, R13); set_next_dst(ppc); } else { GEN_STW(ppc, DYNAREG_ZERO, SDAREL(reg) + gpr*8, R13); set_next_dst(ppc); } }