Adding memory access/etc.

Needs byte swapping.
This commit is contained in:
Ben Vanik 2013-05-22 15:02:26 -07:00
parent 7227ba2693
commit c0dd60bde8
2 changed files with 250 additions and 268 deletions

View File

@ -613,9 +613,9 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
// // Setup locals in the entry block. // // Setup locals in the entry block.
// b.SetInsertPoint(&fn_->getEntryBlock()); // b.SetInsertPoint(&fn_->getEntryBlock());
// locals_.indirection_target = b.CreateAlloca( // locals_.indirection_target = b.CreateAlloca(
// jit_type_nint, 0, "indirection_target"); // jit_type_nuint, 0, "indirection_target");
// locals_.indirection_cia = b.CreateAlloca( // locals_.indirection_cia = b.CreateAlloca(
// jit_type_nint, 0, "indirection_cia"); // jit_type_nuint, 0, "indirection_cia");
// //
// external_indirection_block_ = BasicBlock::Create( // external_indirection_block_ = BasicBlock::Create(
// *context_, "external_indirection_block", fn_, return_block_); // *context_, "external_indirection_block", fn_, return_block_);
@ -695,15 +695,15 @@ void LibjitEmitter::StoreStateValue(size_t offset, jit_type_t type,
void LibjitEmitter::SetupLocals() { void LibjitEmitter::SetupLocals() {
uint64_t spr_t = access_bits_.spr; uint64_t spr_t = access_bits_.spr;
if (spr_t & 0x3) { if (spr_t & 0x3) {
locals_.xer = SetupLocal(jit_type_nint, "xer"); locals_.xer = SetupLocal(jit_type_nuint, "xer");
} }
spr_t >>= 2; spr_t >>= 2;
if (spr_t & 0x3) { if (spr_t & 0x3) {
locals_.lr = SetupLocal(jit_type_nint, "lr"); locals_.lr = SetupLocal(jit_type_nuint, "lr");
} }
spr_t >>= 2; spr_t >>= 2;
if (spr_t & 0x3) { if (spr_t & 0x3) {
locals_.ctr = SetupLocal(jit_type_nint, "ctr"); locals_.ctr = SetupLocal(jit_type_nuint, "ctr");
} }
spr_t >>= 2; spr_t >>= 2;
// TODO: FPCSR // TODO: FPCSR
@ -723,7 +723,7 @@ void LibjitEmitter::SetupLocals() {
for (int n = 0; n < 32; n++) { for (int n = 0; n < 32; n++) {
if (gpr_t & 3) { if (gpr_t & 3) {
//xesnprintfa(name, XECOUNT(name), "r%d", n); //xesnprintfa(name, XECOUNT(name), "r%d", n);
locals_.gpr[n] = SetupLocal(jit_type_nint, name); locals_.gpr[n] = SetupLocal(jit_type_nuint, name);
} }
gpr_t >>= 2; gpr_t >>= 2;
} }
@ -756,19 +756,19 @@ void LibjitEmitter::FillRegisters() {
if (locals_.xer) { if (locals_.xer) {
jit_insn_store(fn_, jit_insn_store(fn_,
locals_.xer, locals_.xer,
LoadStateValue(offsetof(xe_ppc_state_t, xer), jit_type_nint)); LoadStateValue(offsetof(xe_ppc_state_t, xer), jit_type_nuint));
} }
if (locals_.lr) { if (locals_.lr) {
jit_insn_store(fn_, jit_insn_store(fn_,
locals_.lr, locals_.lr,
LoadStateValue(offsetof(xe_ppc_state_t, lr), jit_type_nint)); LoadStateValue(offsetof(xe_ppc_state_t, lr), jit_type_nuint));
} }
if (locals_.ctr) { if (locals_.ctr) {
jit_insn_store(fn_, jit_insn_store(fn_,
locals_.ctr, locals_.ctr,
LoadStateValue(offsetof(xe_ppc_state_t, ctr), jit_type_nint)); LoadStateValue(offsetof(xe_ppc_state_t, ctr), jit_type_nuint));
} }
// Fill the split CR values by extracting each one from the CR. // Fill the split CR values by extracting each one from the CR.
@ -783,7 +783,7 @@ void LibjitEmitter::FillRegisters() {
if (!cr) { if (!cr) {
// Only fetch once. Doing this in here prevents us from having to // Only fetch once. Doing this in here prevents us from having to
// always fetch even if unused. // always fetch even if unused.
cr = LoadStateValue(offsetof(xe_ppc_state_t, cr), jit_type_nint); cr = LoadStateValue(offsetof(xe_ppc_state_t, cr), jit_type_nuint);
} }
// (cr >> 28 - n * 4) & 0xF // (cr >> 28 - n * 4) & 0xF
jit_value_t shamt = jit_value_create_nint_constant( jit_value_t shamt = jit_value_create_nint_constant(
@ -798,7 +798,7 @@ void LibjitEmitter::FillRegisters() {
if (locals_.gpr[n]) { if (locals_.gpr[n]) {
jit_insn_store(fn_, jit_insn_store(fn_,
locals_.gpr[n], locals_.gpr[n],
LoadStateValue(offsetof(xe_ppc_state_t, r) + 8 * n, jit_type_nint)); LoadStateValue(offsetof(xe_ppc_state_t, r) + 8 * n, jit_type_nuint));
} }
} }
@ -821,21 +821,21 @@ void LibjitEmitter::SpillRegisters() {
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_nuint,
jit_insn_load(fn_, 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_nuint,
jit_insn_load(fn_, 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_nuint,
jit_insn_load(fn_, locals_.ctr)); jit_insn_load(fn_, locals_.ctr));
} }
@ -861,7 +861,7 @@ void LibjitEmitter::SpillRegisters() {
if (cr) { if (cr) {
StoreStateValue( StoreStateValue(
offsetof(xe_ppc_state_t, cr), offsetof(xe_ppc_state_t, cr),
jit_type_nint, jit_type_nuint,
cr); cr);
} }
@ -870,7 +870,7 @@ void LibjitEmitter::SpillRegisters() {
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_nuint,
jit_insn_load(fn_, v)); jit_insn_load(fn_, v));
} }
} }
@ -886,64 +886,60 @@ void LibjitEmitter::SpillRegisters() {
} }
} }
//jit_value_t LibjitEmitter::xer_value() { jit_value_t LibjitEmitter::xer_value() {
// XEASSERTNOTNULL(locals_.xer); XEASSERTNOTNULL(locals_.xer);
// IRBuilder<>& b = *builder_; return jit_insn_load(fn_, locals_.xer);
// return b.CreateLoad(locals_.xer); }
//}
// void LibjitEmitter::update_xer_value(jit_value_t value) {
//void LibjitEmitter::update_xer_value(jit_value_t value) { XEASSERTNOTNULL(locals_.xer);
// XEASSERTNOTNULL(locals_.xer);
// IRBuilder<>& b = *builder_; // Extend to 64bits if needed.
// // TODO(benvanik): extend?
// // Extend to 64bits if needed. /*if (!value->getType()->isIntegerTy(64)) {
// if (!value->getType()->isIntegerTy(64)) { value = b.CreateZExt(value, jit_type_nuint);
// value = b.CreateZExt(value, jit_type_nint); }*/
// } jit_insn_store(fn_, locals_.xer, value);
// b.CreateStore(value, locals_.xer); }
//}
//
//void LibjitEmitter::update_xer_with_overflow(jit_value_t value) { //void LibjitEmitter::update_xer_with_overflow(jit_value_t value) {
// XEASSERTNOTNULL(locals_.xer); // XEASSERTNOTNULL(locals_.xer);
// IRBuilder<>& b = *builder_;
// //
// // Expects a i1 indicating overflow. // // Expects a i1 indicating overflow.
// // Trust the caller that if it's larger than that it's already truncated. // // Trust the caller that if it's larger than that it's already truncated.
// if (!value->getType()->isIntegerTy(64)) { // if (!value->getType()->isIntegerTy(64)) {
// value = b.CreateZExt(value, jit_type_nint); // value = b.CreateZExt(value, jit_type_nuint);
// } // }
// //
// jit_value_t xer = xer_value(); // jit_value_t xer = xer_value();
// xer = b.CreateAnd(xer, 0xFFFFFFFFBFFFFFFF); // clear bit 30 // xer = b.CreateAnd(xer, 0xFFFFFFFFBFFFFFFF); // clear bit 30
// xer = b.CreateOr(xer, b.CreateShl(value, 31)); // xer = b.CreateOr(xer, b.CreateShl(value, 31));
// xer = b.CreateOr(xer, b.CreateShl(value, 30)); // xer = b.CreateOr(xer, b.CreateShl(value, 30));
// b.CreateStore(xer, locals_.xer); // jit_insn_store(fn_, locals_.xer, value);
//} //}
// //
//void LibjitEmitter::update_xer_with_carry(jit_value_t value) { //void LibjitEmitter::update_xer_with_carry(jit_value_t value) {
// XEASSERTNOTNULL(locals_.xer); // XEASSERTNOTNULL(locals_.xer);
// IRBuilder<>& b = *builder_;
// //
// // Expects a i1 indicating carry. // // Expects a i1 indicating carry.
// // Trust the caller that if it's larger than that it's already truncated. // // Trust the caller that if it's larger than that it's already truncated.
// if (!value->getType()->isIntegerTy(64)) { // if (!value->getType()->isIntegerTy(64)) {
// value = b.CreateZExt(value, jit_type_nint); // value = b.CreateZExt(value, jit_type_nuint);
// } // }
// //
// jit_value_t xer = xer_value(); // jit_value_t xer = xer_value();
// xer = b.CreateAnd(xer, 0xFFFFFFFFDFFFFFFF); // clear bit 29 // xer = b.CreateAnd(xer, 0xFFFFFFFFDFFFFFFF); // clear bit 29
// xer = b.CreateOr(xer, b.CreateShl(value, 29)); // xer = b.CreateOr(xer, b.CreateShl(value, 29));
// b.CreateStore(xer, locals_.xer); // jit_insn_store(fn_, locals_.xer, value);
//} //}
// //
//void LibjitEmitter::update_xer_with_overflow_and_carry(jit_value_t value) { //void LibjitEmitter::update_xer_with_overflow_and_carry(jit_value_t value) {
// XEASSERTNOTNULL(locals_.xer); // XEASSERTNOTNULL(locals_.xer);
// IRBuilder<>& b = *builder_;
// //
// // Expects a i1 indicating overflow. // // Expects a i1 indicating overflow.
// // Trust the caller that if it's larger than that it's already truncated. // // Trust the caller that if it's larger than that it's already truncated.
// if (!value->getType()->isIntegerTy(64)) { // if (!value->getType()->isIntegerTy(64)) {
// value = b.CreateZExt(value, jit_type_nint); // value = b.CreateZExt(value, jit_type_nuint);
// } // }
// //
// // This is effectively an update_xer_with_overflow followed by an // // This is effectively an update_xer_with_overflow followed by an
@ -953,58 +949,53 @@ void LibjitEmitter::SpillRegisters() {
// xer = b.CreateOr(xer, b.CreateShl(value, 31)); // xer = b.CreateOr(xer, b.CreateShl(value, 31));
// xer = b.CreateOr(xer, b.CreateShl(value, 30)); // xer = b.CreateOr(xer, b.CreateShl(value, 30));
// xer = b.CreateOr(xer, b.CreateShl(value, 29)); // xer = b.CreateOr(xer, b.CreateShl(value, 29));
// b.CreateStore(xer, locals_.xer); // jit_insn_store(fn_, locals_.xer, value);
//} //}
//
//jit_value_t LibjitEmitter::lr_value() { jit_value_t LibjitEmitter::lr_value() {
// XEASSERTNOTNULL(locals_.lr); XEASSERTNOTNULL(locals_.lr);
// IRBuilder<>& b = *builder_; return jit_insn_load(fn_, locals_.lr);
// return b.CreateLoad(locals_.lr); }
//}
// void LibjitEmitter::update_lr_value(jit_value_t value) {
//void LibjitEmitter::update_lr_value(jit_value_t value) { XEASSERTNOTNULL(locals_.lr);
// XEASSERTNOTNULL(locals_.lr);
// IRBuilder<>& b = *builder_; // Extend to 64bits if needed.
// // TODO(benvanik): extend?
// // Extend to 64bits if needed. /*if (!value->getType()->isIntegerTy(64)) {
// if (!value->getType()->isIntegerTy(64)) { value = b.CreateZExt(value, jit_type_nuint);
// value = b.CreateZExt(value, jit_type_nint); }*/
// } jit_insn_store(fn_, locals_.lr, value);
// b.CreateStore(value, locals_.lr); }
//}
// jit_value_t LibjitEmitter::ctr_value() {
//jit_value_t LibjitEmitter::ctr_value() { XEASSERTNOTNULL(locals_.ctr);
// XEASSERTNOTNULL(locals_.ctr); return jit_insn_load(fn_, locals_.ctr);
// IRBuilder<>& b = *builder_; }
//
// return b.CreateLoad(locals_.ctr); void LibjitEmitter::update_ctr_value(jit_value_t value) {
//} XEASSERTNOTNULL(locals_.ctr);
//
//void LibjitEmitter::update_ctr_value(jit_value_t value) { // Extend to 64bits if needed.
// XEASSERTNOTNULL(locals_.ctr); // TODO(benvanik): extend?
// IRBuilder<>& b = *builder_; /*if (!value->getType()->isIntegerTy(64)) {
// value = b.CreateZExt(value, jit_type_nuint);
// // Extend to 64bits if needed. }*/
// if (!value->getType()->isIntegerTy(64)) { jit_insn_store(fn_, locals_.ctr, value);
// value = b.CreateZExt(value, jit_type_nint); }
// }
// b.CreateStore(value, locals_.ctr);
//}
//
//jit_value_t LibjitEmitter::cr_value(uint32_t n) { //jit_value_t LibjitEmitter::cr_value(uint32_t n) {
// XEASSERT(n >= 0 && n < 8); // XEASSERT(n >= 0 && n < 8);
// XEASSERTNOTNULL(locals_.cr[n]); // XEASSERTNOTNULL(locals_.cr[n]);
// IRBuilder<>& b = *builder_;
// //
// jit_value_t v = b.CreateLoad(locals_.cr[n]); // jit_value_t v = jit_insn_load(fn_, locals_.cr[n]);
// v = b.CreateZExt(v, jit_type_nint); // v = b.CreateZExt(v, jit_type_nuint);
// return v; // return v;
//} //}
// //
//void LibjitEmitter::update_cr_value(uint32_t n, jit_value_t value) { //void LibjitEmitter::update_cr_value(uint32_t n, jit_value_t value) {
// XEASSERT(n >= 0 && n < 8); // XEASSERT(n >= 0 && n < 8);
// XEASSERTNOTNULL(locals_.cr[n]); // XEASSERTNOTNULL(locals_.cr[n]);
// IRBuilder<>& b = *builder_;
// //
// // Truncate to 8 bits if needed. // // Truncate to 8 bits if needed.
// // TODO(benvanik): also widen? // // TODO(benvanik): also widen?
@ -1017,7 +1008,6 @@ void LibjitEmitter::SpillRegisters() {
// //
//void LibjitEmitter::update_cr_with_cond( //void LibjitEmitter::update_cr_with_cond(
// uint32_t n, jit_value_t lhs, jit_value_t rhs, bool is_signed) { // uint32_t n, jit_value_t lhs, jit_value_t rhs, bool is_signed) {
// IRBuilder<>& b = *builder_;
// //
// // bit0 = RA < RB // // bit0 = RA < RB
// // bit1 = RA > RB // // bit1 = RA > RB
@ -1046,187 +1036,180 @@ void LibjitEmitter::SpillRegisters() {
// // Insert the 4 bits into their location in the CR. // // Insert the 4 bits into their location in the CR.
// update_cr_value(n, c); // update_cr_value(n, c);
//} //}
//
//jit_value_t LibjitEmitter::gpr_value(uint32_t n) { jit_value_t LibjitEmitter::gpr_value(uint32_t n) {
// XEASSERT(n >= 0 && n < 32); XEASSERT(n >= 0 && n < 32);
// XEASSERTNOTNULL(locals_.gpr[n]); XEASSERTNOTNULL(locals_.gpr[n]);
// IRBuilder<>& b = *builder_;
// // Actually r0 is writable, even though nobody should ever do that.
// // Actually r0 is writable, even though nobody should ever do that. // Perhaps we can check usage and enable this if safe?
// // Perhaps we can check usage and enable this if safe? // if (n == 0) {
// // if (n == 0) { // return jit_value_create_nuint_constant(fn_, jit_type_nint, 0);
// // // Always force zero to a constant - this should help LLVM. // }
// // return b.getInt64(0);
// // } return jit_insn_load(fn_, locals_.gpr[n]);
// }
// return b.CreateLoad(locals_.gpr[n]);
//} void LibjitEmitter::update_gpr_value(uint32_t n, jit_value_t value) {
// XEASSERT(n >= 0 && n < 32);
//void LibjitEmitter::update_gpr_value(uint32_t n, jit_value_t value) { XEASSERTNOTNULL(locals_.gpr[n]);
// XEASSERT(n >= 0 && n < 32);
// XEASSERTNOTNULL(locals_.gpr[n]); // See above - r0 can be written.
// IRBuilder<>& b = *builder_; // if (n == 0) {
// // // Ignore writes to zero.
// // See above - r0 can be written. // return;
// // if (n == 0) { // }
// // // Ignore writes to zero.
// // return; // Extend to 64bits if needed.
// // } // TODO(benvanik): extend?
// //jit_insn_convert(fn_, value, jit_type_nuint, 0);
// // Extend to 64bits if needed. /*if (!value->getType()->isIntegerTy(64)) {
// if (!value->getType()->isIntegerTy(64)) { value = b.CreateZExt(value, jit_type_nuint);
// value = b.CreateZExt(value, jit_type_nint); }*/
// }
// jit_insn_store(fn_, locals_.gpr[n], value);
// b.CreateStore(value, locals_.gpr[n]); }
//}
// jit_value_t LibjitEmitter::fpr_value(uint32_t n) {
//jit_value_t LibjitEmitter::fpr_value(uint32_t n) { XEASSERT(n >= 0 && n < 32);
// XEASSERT(n >= 0 && n < 32); XEASSERTNOTNULL(locals_.fpr[n]);
// XEASSERTNOTNULL(locals_.fpr[n]); return jit_insn_load(fn_, locals_.fpr[n]);
// IRBuilder<>& b = *builder_; }
// return b.CreateLoad(locals_.fpr[n]);
//} void LibjitEmitter::update_fpr_value(uint32_t n, jit_value_t value) {
// XEASSERT(n >= 0 && n < 32);
//void LibjitEmitter::update_fpr_value(uint32_t n, jit_value_t value) { XEASSERTNOTNULL(locals_.fpr[n]);
// XEASSERT(n >= 0 && n < 32); jit_insn_store(fn_, locals_.fpr[n], value);
// XEASSERTNOTNULL(locals_.fpr[n]); }
// IRBuilder<>& b = *builder_;
// value = b.CreateFPExtOrFPTrunc(value, jit_type_float64); jit_value_t LibjitEmitter::GetMemoryAddress(uint32_t cia, jit_value_t addr) {
// b.CreateStore(value, locals_.fpr[n]); // Input address is always in 32-bit space.
//} // TODO(benvanik): is this required? It's one extra instruction on every
// // access...
//jit_value_t LibjitEmitter::GetMembase() { addr = jit_insn_and(fn_, addr,
// jit_value_t v = gen_module_->getGlobalVariable("xe_memory_base"); jit_value_create_nint_constant(fn_, jit_type_nuint, UINT_MAX));
// return builder_->CreateLoad(v);
//} // Add runtime memory address checks, if needed.
// // if (FLAGS_memory_address_verification) {
//jit_value_t LibjitEmitter::GetMemoryAddress(uint32_t cia, jit_value_t addr) { // BasicBlock* invalid_bb = BasicBlock::Create(*context_, "", fn_);
// IRBuilder<>& b = *builder_; // BasicBlock* valid_bb = BasicBlock::Create(*context_, "", fn_);
//
// // Input address is always in 32-bit space. // // The heap starts at 0x1000 - if we write below that we're boned.
// addr = b.CreateAnd(addr, UINT_MAX); // jit_value_t gt = b.CreateICmpUGE(addr, b.getInt64(0x00001000));
// // b.CreateCondBr(gt, valid_bb, invalid_bb);
// // Add runtime memory address checks, if needed.
// if (FLAGS_memory_address_verification) { // b.SetInsertPoint(invalid_bb);
// BasicBlock* invalid_bb = BasicBlock::Create(*context_, "", fn_); // jit_value_t access_violation = gen_module_->getFunction("XeAccessViolation");
// BasicBlock* valid_bb = BasicBlock::Create(*context_, "", fn_); // SpillRegisters();
// // b.CreateCall3(access_violation,
// // The heap starts at 0x1000 - if we write below that we're boned. // fn_->arg_begin(),
// jit_value_t gt = b.CreateICmpUGE(addr, b.getInt64(0x00001000)); // b.getInt32(cia),
// b.CreateCondBr(gt, valid_bb, invalid_bb); // addr);
// // b.CreateBr(valid_bb);
// b.SetInsertPoint(invalid_bb);
// jit_value_t access_violation = gen_module_->getFunction("XeAccessViolation"); // b.SetInsertPoint(valid_bb);
// SpillRegisters(); // }
// b.CreateCall3(access_violation,
// fn_->arg_begin(), // Rebase off of memory base pointer.
// b.getInt32(cia), // We could store the memory base as a global value (or indirection off of
// addr); // state) if we wanted to avoid embedding runtime values into the code.
// b.CreateBr(valid_bb); jit_nuint membase = (jit_nuint)xe_memory_addr(memory_, 0);
// return jit_insn_add_relative(fn_, addr, membase);
// b.SetInsertPoint(valid_bb); }
// }
// jit_value_t LibjitEmitter::ReadMemory(
// // Rebase off of memory base pointer. uint32_t cia, jit_value_t addr, uint32_t size, bool acquire) {
// return b.CreateInBoundsGEP(GetMembase(), addr); jit_type_t data_type = NULL;
//} bool needs_swap = false;
// switch (size) {
//jit_value_t LibjitEmitter::ReadMemory( case 1:
// uint32_t cia, jit_value_t addr, uint32_t size, bool acquire) { data_type = jit_type_ubyte;
// jit_type_t dataTy = NULL; break;
// bool needs_swap = false; case 2:
// switch (size) { data_type = jit_type_ushort;
// case 1: needs_swap = true;
// dataTy = jit_type_ubyte; break;
// break; case 4:
// case 2: data_type = jit_type_uint;
// dataTy = jit_type_ushort; needs_swap = true;
// needs_swap = true; break;
// break; case 8:
// case 4: data_type = jit_type_ulong;
// dataTy = jit_type_uint; needs_swap = true;
// needs_swap = true; break;
// break; default:
// case 8: XEASSERTALWAYS();
// dataTy = jit_type_ulong; return NULL;
// needs_swap = true; }
// break;
// default: jit_value_t address = GetMemoryAddress(cia, addr);
// XEASSERTALWAYS(); jit_value_t value = jit_insn_load_relative(fn_, address, 0, data_type);
// return NULL; if (acquire) {
// } // TODO(benvanik): acquire semantics.
// PointerType* pointerTy = PointerType::getUnqual(dataTy); // load_value->setAlignment(size);
// // load_value->setVolatile(true);
// jit_value_t address = GetMemoryAddress(cia, addr); // load_value->setAtomic(Acquire);
// jit_value_t ptr = b.CreatePointerCast(address, pointerTy); jit_value_set_volatile(value);
// LoadInst* load_value = b.CreateLoad(ptr); }
// if (acquire) {
// load_value->setAlignment(size); // Swap after loading.
// load_value->setVolatile(true); // TODO(benvanik): find a way to avoid this!
// load_value->setAtomic(Acquire); if (needs_swap) {
// } // Function* bswap = Intrinsic::getDeclaration(
// jit_value_t value = load_value; // gen_module_, Intrinsic::bswap, data_type);
// // value = b.CreateCall(bswap, value);
// // Swap after loading. }
// // TODO(benvanik): find a way to avoid this!
// if (needs_swap) { return value;
// Function* bswap = Intrinsic::getDeclaration( }
// gen_module_, Intrinsic::bswap, dataTy);
// value = b.CreateCall(bswap, value); void LibjitEmitter::WriteMemory(
// } uint32_t cia, jit_value_t addr, uint32_t size, jit_value_t value,
// bool release) {
// return value; jit_type_t data_type = NULL;
//} bool needs_swap = false;
// switch (size) {
//void LibjitEmitter::WriteMemory( case 1:
// uint32_t cia, jit_value_t addr, uint32_t size, jit_value_t value, bool release) { data_type = jit_type_ubyte;
// IRBuilder<>& b = *builder_; break;
// case 2:
// jit_type_t dataTy = NULL; data_type = jit_type_ushort;
// bool needs_swap = false; needs_swap = true;
// switch (size) { break;
// case 1: case 4:
// dataTy = jit_type_ubyte; data_type = jit_type_uint;
// break; needs_swap = true;
// case 2: break;
// dataTy = jit_type_ushort; case 8:
// needs_swap = true; data_type = jit_type_ulong;
// break; needs_swap = true;
// case 4: break;
// dataTy = jit_type_uint; default:
// needs_swap = true; XEASSERTALWAYS();
// break; return;
// case 8: }
// dataTy = jit_type_ulong;
// needs_swap = true; jit_value_t address = GetMemoryAddress(cia, addr);
// break;
// default: // Truncate, if required.
// XEASSERTALWAYS(); if (jit_value_get_type(value) != data_type) {
// return; value = jit_insn_convert(fn_, value, data_type, 0);
// } }
// PointerType* pointerTy = PointerType::getUnqual(dataTy);
// // Swap before storing.
// jit_value_t address = GetMemoryAddress(cia, addr); // TODO(benvanik): find a way to avoid this!
// jit_value_t ptr = b.CreatePointerCast(address, pointerTy); if (needs_swap) {
// // Function* bswap = Intrinsic::getDeclaration(
// // Truncate, if required. // gen_module_, Intrinsic::bswap, data_type);
// if (value->getType() != dataTy) { // value = b.CreateCall(bswap, value);
// value = b.CreateTrunc(value, dataTy); }
// }
// // TODO(benvanik): release semantics
// // Swap before storing. // if (release) {
// // TODO(benvanik): find a way to avoid this! // store_value->setAlignment(size);
// if (needs_swap) { // store_value->setVolatile(true);
// Function* bswap = Intrinsic::getDeclaration( // store_value->setAtomic(Release);
// gen_module_, Intrinsic::bswap, dataTy); // }
// value = b.CreateCall(bswap, value);
// } jit_insn_store_relative(fn_, address, 0, value);
// }
// StoreInst* store_value = b.CreateStore(value, ptr);
// if (release) {
// store_value->setAlignment(size);
// store_value->setVolatile(true);
// store_value->setAtomic(Release);
// }
//}

View File

@ -76,7 +76,6 @@ public:
jit_value_t fpr_value(uint32_t n); jit_value_t fpr_value(uint32_t n);
void update_fpr_value(uint32_t n, jit_value_t value); void update_fpr_value(uint32_t n, jit_value_t value);
jit_value_t GetMembase();
jit_value_t GetMemoryAddress(uint32_t cia, jit_value_t addr); jit_value_t GetMemoryAddress(uint32_t cia, jit_value_t addr);
jit_value_t ReadMemory( jit_value_t ReadMemory(
uint32_t cia, jit_value_t addr, uint32_t size, bool acquire = false); uint32_t cia, jit_value_t addr, uint32_t size, bool acquire = false);