Setting up register fill/spill.

This commit is contained in:
Ben Vanik 2013-05-22 13:37:44 -07:00
parent 16d2b73a73
commit 7227ba2693
3 changed files with 134 additions and 138 deletions

View File

@ -676,28 +676,21 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
// //
// return 0; // return 0;
//} //}
//
//jit_value_t LibjitEmitter::LoadStateValue(uint32_t offset, jit_type_t type, jit_value_t LibjitEmitter::LoadStateValue(size_t offset, jit_type_t type,
// const char* name) { const char* name) {
// IRBuilder<>& b = *builder_; // Load from ppc_state[offset].
// PointerType* pointerTy = PointerType::getUnqual(type); // TODO(benvanik): tag with debug info?
// Function::arg_iterator args = fn_->arg_begin(); return jit_insn_load_relative(
// jit_value_t state_ptr = args; fn_, jit_value_get_param(fn_, 0), offset, type);
// jit_value_t address = b.CreateInBoundsGEP(state_ptr, b.getInt32(offset)); }
// jit_value_t ptr = b.CreatePointerCast(address, pointerTy);
// return b.CreateLoad(ptr, name); void LibjitEmitter::StoreStateValue(size_t offset, jit_type_t type,
//} jit_value_t value) {
// // Store to ppc_state[offset].
//void LibjitEmitter::StoreStateValue(uint32_t offset, jit_type_t type, jit_insn_store_relative(
// jit_value_t value) { fn_, jit_value_get_param(fn_, 0), offset, value);
// IRBuilder<>& b = *builder_; }
// PointerType* pointerTy = PointerType::getUnqual(type);
// Function::arg_iterator args = fn_->arg_begin();
// jit_value_t state_ptr = args;
// jit_value_t address = b.CreateInBoundsGEP(state_ptr, b.getInt32(offset));
// jit_value_t ptr = b.CreatePointerCast(address, pointerTy);
// b.CreateStore(value, ptr);
//}
void LibjitEmitter::SetupLocals() { void LibjitEmitter::SetupLocals() {
uint64_t spr_t = access_bits_.spr; uint64_t spr_t = access_bits_.spr;
@ -753,10 +746,6 @@ jit_value_t LibjitEmitter::SetupLocal(jit_type_t type, const char* name) {
return value; return value;
} }
//jit_value_t LibjitEmitter::cia_value() {
// return builder_->getInt32(cia_);
//}
void LibjitEmitter::FillRegisters() { void LibjitEmitter::FillRegisters() {
// This updates all of the local register values from the state memory. // This updates all of the local register values from the state memory.
// It should be called on function entry for initial setup and after any // It should be called on function entry for initial setup and after any
@ -764,58 +753,63 @@ void LibjitEmitter::FillRegisters() {
// TODO(benvanik): use access flags to see if we need to do reads/writes. // TODO(benvanik): use access flags to see if we need to do reads/writes.
// if (locals_.xer) { if (locals_.xer) {
// b.CreateStore(LoadStateValue( jit_insn_store(fn_,
// offsetof(xe_ppc_state_t, xer), locals_.xer,
// jit_type_nint), locals_.xer); LoadStateValue(offsetof(xe_ppc_state_t, xer), jit_type_nint));
// } }
// if (locals_.lr) { if (locals_.lr) {
// b.CreateStore(LoadStateValue( jit_insn_store(fn_,
// offsetof(xe_ppc_state_t, lr), locals_.lr,
// jit_type_nint), locals_.lr); LoadStateValue(offsetof(xe_ppc_state_t, lr), jit_type_nint));
// } }
// if (locals_.ctr) { if (locals_.ctr) {
// b.CreateStore(LoadStateValue( jit_insn_store(fn_,
// offsetof(xe_ppc_state_t, ctr), locals_.ctr,
// jit_type_nint), locals_.ctr); LoadStateValue(offsetof(xe_ppc_state_t, ctr), jit_type_nint));
// } }
// // Fill the split CR values by extracting each one from the CR. // Fill the split CR values by extracting each one from the CR.
// // This could probably be done faster via an extractvalues or something. // This could probably be done faster via an extractvalues or something.
// // Perhaps we could also change it to be a vector<8*i8>. // Perhaps we could also change it to be a vector<8*i8>.
// jit_value_t cr = NULL; jit_value_t cr = NULL;
// for (size_t n = 0; n < XECOUNT(locals_.cr); n++) { for (size_t n = 0; n < XECOUNT(locals_.cr); n++) {
// jit_value_t cr_n = locals_.cr[n]; jit_value_t cr_n = locals_.cr[n];
// if (!cr_n) { if (!cr_n) {
// continue; continue;
// } }
// if (!cr) { if (!cr) {
// cr = LoadStateValue( // Only fetch once. Doing this in here prevents us from having to
// offsetof(xe_ppc_state_t, cr), // always fetch even if unused.
// jit_type_nint); cr = LoadStateValue(offsetof(xe_ppc_state_t, cr), jit_type_nint);
// } }
// b.CreateStore( // (cr >> 28 - n * 4) & 0xF
// b.CreateTrunc(b.CreateAnd(b.CreateLShr(cr, (28 - n * 4)), 0xF), jit_value_t shamt = jit_value_create_nint_constant(
// b.getInt8Ty()), cr_n); fn_, jit_type_nuint, 28 - n * 4);
// } jit_insn_store(fn_, cr_n,
jit_insn_and(fn_,
jit_insn_ushr(fn_, cr, shamt),
jit_value_create_nint_constant(fn_, jit_type_ubyte, 0xF)));
}
// for (size_t n = 0; n < XECOUNT(locals_.gpr); n++) { for (size_t n = 0; n < XECOUNT(locals_.gpr); n++) {
// if (locals_.gpr[n]) { if (locals_.gpr[n]) {
// b.CreateStore(LoadStateValue( jit_insn_store(fn_,
// (uint32_t)offsetof(xe_ppc_state_t, r) + 8 * n, locals_.gpr[n],
// jit_type_nint), locals_.gpr[n]); LoadStateValue(offsetof(xe_ppc_state_t, r) + 8 * n, jit_type_nint));
// } }
// } }
// for (size_t n = 0; n < XECOUNT(locals_.fpr); n++) { for (size_t n = 0; n < XECOUNT(locals_.fpr); n++) {
// if (locals_.fpr[n]) { if (locals_.fpr[n]) {
// b.CreateStore(LoadStateValue( jit_insn_store(fn_,
// (uint32_t)offsetof(xe_ppc_state_t, f) + 8 * n, locals_.fpr[n],
// jit_type_float64), locals_.fpr[n]); LoadStateValue(offsetof(xe_ppc_state_t, f) + 8 * n,
// } jit_type_float64));
// } }
}
} }
void LibjitEmitter::SpillRegisters() { void LibjitEmitter::SpillRegisters() {
@ -824,68 +818,72 @@ void LibjitEmitter::SpillRegisters() {
// TODO(benvanik): only flush if actually required, or selective flushes. // TODO(benvanik): only flush if actually required, or selective flushes.
// if (locals_.xer) { if (locals_.xer) {
// StoreStateValue( StoreStateValue(
// offsetof(xe_ppc_state_t, xer), offsetof(xe_ppc_state_t, xer),
// jit_type_nint, jit_type_nint,
// b.CreateLoad(locals_.xer)); jit_insn_load(fn_, locals_.xer));
// } }
// if (locals_.lr) { if (locals_.lr) {
// StoreStateValue( StoreStateValue(
// offsetof(xe_ppc_state_t, lr), offsetof(xe_ppc_state_t, lr),
// jit_type_nint, jit_type_nint,
// b.CreateLoad(locals_.lr)); jit_insn_load(fn_, locals_.lr));
// } }
// if (locals_.ctr) { if (locals_.ctr) {
// StoreStateValue( StoreStateValue(
// offsetof(xe_ppc_state_t, ctr), offsetof(xe_ppc_state_t, ctr),
// jit_type_nint, jit_type_nint,
// b.CreateLoad(locals_.ctr)); jit_insn_load(fn_, locals_.ctr));
// } }
// // Stitch together all split CR values. // Stitch together all split CR values.
// // TODO(benvanik): don't flush across calls? // TODO(benvanik): don't flush across calls?
// jit_value_t cr = NULL; jit_value_t cr = NULL;
// for (size_t n = 0; n < XECOUNT(locals_.cr); n++) { for (size_t n = 0; n < XECOUNT(locals_.cr); n++) {
// jit_value_t cr_n = locals_.cr[n]; jit_value_t cr_n = locals_.cr[n];
// if (!cr_n) { if (!cr_n) {
// continue; continue;
// } }
// cr_n = b.CreateZExt(b.CreateLoad(cr_n), jit_type_nint); // cr |= (cr_n << n * 4)
// if (!cr) { jit_value_t shamt = jit_value_create_nint_constant(
// cr = b.CreateShl(cr_n, n * 4); fn_, jit_type_nuint, n * 4);
// } else { cr_n = jit_insn_convert(fn_, jit_insn_load(fn_, cr_n), jit_type_nuint, 0);
// cr = b.CreateOr(cr, b.CreateShl(cr_n, n * 4)); cr_n = jit_insn_shl(fn_, cr_n, shamt);
// } if (!cr) {
// } cr = cr_n;
// if (cr) { } else {
// StoreStateValue( cr = jit_insn_or(fn_, cr, cr_n);
// offsetof(xe_ppc_state_t, cr), }
// jit_type_nint, }
// cr); if (cr) {
// } StoreStateValue(
offsetof(xe_ppc_state_t, cr),
jit_type_nint,
cr);
}
// for (uint32_t n = 0; n < XECOUNT(locals_.gpr); n++) { for (uint32_t n = 0; n < XECOUNT(locals_.gpr); n++) {
// jit_value_t v = locals_.gpr[n]; jit_value_t v = locals_.gpr[n];
// if (v) { if (v) {
// StoreStateValue( StoreStateValue(
// offsetof(xe_ppc_state_t, r) + 8 * n, offsetof(xe_ppc_state_t, r) + 8 * n,
// jit_type_nint, jit_type_nint,
// b.CreateLoad(locals_.gpr[n])); jit_insn_load(fn_, v));
// } }
// } }
// for (uint32_t n = 0; n < XECOUNT(locals_.fpr); n++) { for (uint32_t n = 0; n < XECOUNT(locals_.fpr); n++) {
// jit_value_t v = locals_.fpr[n]; jit_value_t v = locals_.fpr[n];
// if (v) { if (v) {
// StoreStateValue( StoreStateValue(
// offsetof(xe_ppc_state_t, f) + 8 * n, offsetof(xe_ppc_state_t, f) + 8 * n,
// jit_type_float64, jit_type_float64,
// b.CreateLoad(locals_.fpr[n])); jit_insn_load(fn_, v));
// } }
// } }
} }
//jit_value_t LibjitEmitter::xer_value() { //jit_value_t LibjitEmitter::xer_value() {

View File

@ -46,11 +46,9 @@ public:
int GenerateIndirectionBranch(uint32_t cia, jit_value_t target, int GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
bool lk, bool likely_local); bool lk, bool likely_local);
jit_value_t LoadStateValue(uint32_t offset, jit_type_t type, jit_value_t LoadStateValue(size_t offset, jit_type_t type,
const char* name = ""); const char* name = "");
void StoreStateValue(uint32_t offset, jit_type_t type, jit_value_t value); void StoreStateValue(size_t offset, jit_type_t type, jit_value_t value);
jit_value_t cia_value();
jit_value_t SetupLocal(jit_type_t type, const char* name); jit_value_t SetupLocal(jit_type_t type, const char* name);
void FillRegisters(); void FillRegisters();

View File

@ -56,10 +56,6 @@ typedef struct XECACHEALIGN64 xe_ppc_state {
uint64_t lr; // Link register uint64_t lr; // Link register
uint64_t ctr; // Count register uint64_t ctr; // Count register
uint64_t r[32]; // General purpose registers
xe_float4_t v[128]; // VMX128 vector registers
double f[32]; // Floating-point registers
union { union {
uint32_t value; uint32_t value;
struct { struct {
@ -134,6 +130,10 @@ typedef struct XECACHEALIGN64 xe_ppc_state {
} bits; } bits;
} fpscr; // Floating-point status and control register } fpscr; // Floating-point status and control register
uint64_t r[32]; // General purpose registers
xe_float4_t v[128]; // VMX128 vector registers
double f[32]; // Floating-point registers
// uint32_t get_fprf() { // uint32_t get_fprf() {
// return fpscr.value & 0x000F8000; // return fpscr.value & 0x000F8000;
// } // }