Basic control instructions (no indirection branches yet).
This commit is contained in:
parent
1bcb3e8f92
commit
f2c16c24f3
File diff suppressed because it is too large
Load Diff
|
@ -483,26 +483,26 @@ void LibjitEmitter::GenerateBasicBlock(FunctionBlock* block) {
|
||||||
//jit_insn_mark_breakpoint(fn_, 1, ia);
|
//jit_insn_mark_breakpoint(fn_, 1, ia);
|
||||||
|
|
||||||
if (FLAGS_trace_instructions) {
|
if (FLAGS_trace_instructions) {
|
||||||
// SpillRegisters();
|
SpillRegisters();
|
||||||
// jit_insn_call_native(
|
jit_insn_call_native(
|
||||||
// fn_,
|
fn_,
|
||||||
// "XeTraceInstruction",
|
"XeTraceInstruction",
|
||||||
// global_exports_.XeTraceInstruction,
|
global_exports_.XeTraceInstruction,
|
||||||
// global_export_signature_3_,
|
global_export_signature_3_,
|
||||||
// trace_args, XECOUNT(trace_args),
|
trace_args, XECOUNT(trace_args),
|
||||||
// 0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i.type) {
|
if (!i.type) {
|
||||||
XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
|
XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
|
||||||
// SpillRegisters();
|
SpillRegisters();
|
||||||
// jit_insn_call_native(
|
jit_insn_call_native(
|
||||||
// fn_,
|
fn_,
|
||||||
// "XeInvalidInstruction",
|
"XeInvalidInstruction",
|
||||||
// global_exports_.XeInvalidInstruction,
|
global_exports_.XeInvalidInstruction,
|
||||||
// global_export_signature_3_,
|
global_export_signature_3_,
|
||||||
// trace_args, XECOUNT(trace_args),
|
trace_args, XECOUNT(trace_args),
|
||||||
// 0);
|
0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,10 +697,15 @@ int LibjitEmitter::branch_to_block(uint32_t address) {
|
||||||
|
|
||||||
int LibjitEmitter::branch_to_block_if(uint32_t address, jit_value_t value) {
|
int LibjitEmitter::branch_to_block_if(uint32_t address, jit_value_t value) {
|
||||||
std::map<uint32_t, jit_label_t>::iterator it = bbs_.find(address);
|
std::map<uint32_t, jit_label_t>::iterator it = bbs_.find(address);
|
||||||
|
if (value) {
|
||||||
return jit_insn_branch_if(fn_, value, &it->second);
|
return jit_insn_branch_if(fn_, value, &it->second);
|
||||||
|
} else {
|
||||||
|
return jit_insn_branch(fn_, &it->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int LibjitEmitter::branch_to_block_if_not(uint32_t address, jit_value_t value) {
|
int LibjitEmitter::branch_to_block_if_not(uint32_t address, jit_value_t value) {
|
||||||
|
XEASSERTNOTNULL(value);
|
||||||
std::map<uint32_t, jit_label_t>::iterator it = bbs_.find(address);
|
std::map<uint32_t, jit_label_t>::iterator it = bbs_.find(address);
|
||||||
return jit_insn_branch_if_not(fn_, value, &it->second);
|
return jit_insn_branch_if_not(fn_, value, &it->second);
|
||||||
}
|
}
|
||||||
|
@ -717,30 +722,37 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
|
||||||
return jit_insn_branch_if_not(fn_, value, &return_block_);
|
return jit_insn_branch_if_not(fn_, value, &return_block_);
|
||||||
}
|
}
|
||||||
|
|
||||||
//BasicBlock* LibjitEmitter::GetNextBasicBlock() {
|
int LibjitEmitter::call_function(FunctionSymbol* target_symbol,
|
||||||
// std::map<uint32_t, BasicBlock*>::iterator it = bbs_.find(
|
jit_value_t lr, bool tail) {
|
||||||
// fn_block_->start_address);
|
PrepareFunction(target_symbol);
|
||||||
// ++it;
|
jit_function_t target_fn = (jit_function_t)target_symbol->impl_value;
|
||||||
// if (it != bbs_.end()) {
|
XEASSERTNOTNULL(target_fn);
|
||||||
// return it->second;
|
int flags = 0;
|
||||||
// }
|
if (tail) {
|
||||||
// return NULL;
|
flags |= JIT_CALL_TAIL;
|
||||||
//}
|
}
|
||||||
|
jit_value_t args[] = {jit_value_get_param(fn_, 0), lr};
|
||||||
|
jit_insn_call(fn_, target_symbol->name(), target_fn, fn_signature_,
|
||||||
|
args, XECOUNT(args), flags);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LibjitEmitter::GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
|
||||||
|
bool lk, bool likely_local) {
|
||||||
|
// This function is called by the control emitters when they know that an
|
||||||
|
// indirect branch is required.
|
||||||
|
// It first tries to see if the branch is to an address within the function
|
||||||
|
// and, if so, uses a local switch table. If that fails because we don't know
|
||||||
|
// the block the function is regenerated (ACK!). If the target is external
|
||||||
|
// then an external call occurs.
|
||||||
|
|
||||||
|
// TODO(benvanik): port indirection.
|
||||||
|
//XEASSERTALWAYS();
|
||||||
|
|
||||||
//int LibjitEmitter::GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
|
|
||||||
// bool lk, bool likely_local) {
|
|
||||||
// // This function is called by the control emitters when they know that an
|
|
||||||
// // indirect branch is required.
|
|
||||||
// // It first tries to see if the branch is to an address within the function
|
|
||||||
// // and, if so, uses a local switch table. If that fails because we don't know
|
|
||||||
// // the block the function is regenerated (ACK!). If the target is external
|
|
||||||
// // then an external call occurs.
|
|
||||||
//
|
|
||||||
// IRBuilder<>& b = *builder_;
|
|
||||||
// BasicBlock* next_block = GetNextBasicBlock();
|
// BasicBlock* next_block = GetNextBasicBlock();
|
||||||
//
|
|
||||||
// PushInsertPoint();
|
// PushInsertPoint();
|
||||||
//
|
|
||||||
// // Request builds of the indirection blocks on demand.
|
// // Request builds of the indirection blocks on demand.
|
||||||
// // We can't build here because we don't know what registers will be needed
|
// // We can't build here because we don't know what registers will be needed
|
||||||
// // yet, so we just create the blocks and let GenerateSharedBlocks handle it
|
// // yet, so we just create the blocks and let GenerateSharedBlocks handle it
|
||||||
|
@ -752,7 +764,7 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
|
||||||
// jit_type_nuint, 0, "indirection_target");
|
// jit_type_nuint, 0, "indirection_target");
|
||||||
// locals_.indirection_cia = b.CreateAlloca(
|
// locals_.indirection_cia = b.CreateAlloca(
|
||||||
// jit_type_nuint, 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_);
|
||||||
// }
|
// }
|
||||||
|
@ -760,9 +772,9 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
|
||||||
// internal_indirection_block_ = BasicBlock::Create(
|
// internal_indirection_block_ = BasicBlock::Create(
|
||||||
// *context_, "internal_indirection_block", fn_, return_block_);
|
// *context_, "internal_indirection_block", fn_, return_block_);
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// PopInsertPoint();
|
// PopInsertPoint();
|
||||||
//
|
|
||||||
// // Check to see if the target address is within the function.
|
// // Check to see if the target address is within the function.
|
||||||
// // If it is jump to that basic block. If the basic block is not found it means
|
// // If it is jump to that basic block. If the basic block is not found it means
|
||||||
// // we have a jump inside the function that wasn't identified via static
|
// // we have a jump inside the function that wasn't identified via static
|
||||||
|
@ -779,7 +791,7 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
|
||||||
// internal_indirection_block_, external_indirection_block_);
|
// internal_indirection_block_, external_indirection_block_);
|
||||||
// return 0;
|
// return 0;
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// // If we are LK=0 jump to the shared indirection block. This prevents us
|
// // If we are LK=0 jump to the shared indirection block. This prevents us
|
||||||
// // from needing to fill the registers again after the call and shares more
|
// // from needing to fill the registers again after the call and shares more
|
||||||
// // code.
|
// // code.
|
||||||
|
@ -790,28 +802,35 @@ int LibjitEmitter::branch_to_return_if_not(jit_value_t value) {
|
||||||
// } else {
|
// } else {
|
||||||
// // Slowest path - spill, call the external function, and fill.
|
// // Slowest path - spill, call the external function, and fill.
|
||||||
// // We should avoid this at all costs.
|
// // We should avoid this at all costs.
|
||||||
//
|
|
||||||
// // Spill registers. We could probably share this.
|
// // Spill registers. We could probably share this.
|
||||||
// SpillRegisters();
|
// SpillRegisters();
|
||||||
//
|
|
||||||
// // TODO(benvanik): keep function pointer lookup local.
|
// // Issue the full indirection branch.
|
||||||
// jit_value_t indirect_branch = gen_module_->getFunction("XeIndirectBranch");
|
// jit_value_t branch_args[] = {
|
||||||
// b.CreateCall3(indirect_branch,
|
// jit_value_get_param(fn_, 0),
|
||||||
// fn_->arg_begin(),
|
|
||||||
// target,
|
// target,
|
||||||
// b.getInt64(cia));
|
// get_uint64(cia),
|
||||||
//
|
// };
|
||||||
|
// jit_insn_call_native(
|
||||||
|
// fn_,
|
||||||
|
// "XeIndirectBranch",
|
||||||
|
// global_exports_.XeIndirectBranch,
|
||||||
|
// global_export_signature_3_,
|
||||||
|
// branch_args, XECOUNT(branch_args),
|
||||||
|
// 0);
|
||||||
|
|
||||||
// if (next_block) {
|
// if (next_block) {
|
||||||
// // Only refill if not a tail call.
|
// // Only refill if not a tail call.
|
||||||
// FillRegisters();
|
// FillRegisters();
|
||||||
// b.CreateBr(next_block);
|
// b.CreateBr(next_block);
|
||||||
// } else {
|
// } else {
|
||||||
// b.CreateRetVoid();
|
// jit_insn_return(fn_, NULL);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// return 0;
|
return 0;
|
||||||
//}
|
}
|
||||||
|
|
||||||
jit_value_t LibjitEmitter::LoadStateValue(size_t offset, jit_type_t type,
|
jit_value_t LibjitEmitter::LoadStateValue(size_t offset, jit_type_t type,
|
||||||
const char* name) {
|
const char* name) {
|
||||||
|
|
|
@ -55,6 +55,8 @@ public:
|
||||||
int branch_to_return();
|
int branch_to_return();
|
||||||
int branch_to_return_if(jit_value_t value);
|
int branch_to_return_if(jit_value_t value);
|
||||||
int branch_to_return_if_not(jit_value_t value);
|
int branch_to_return_if_not(jit_value_t value);
|
||||||
|
int call_function(sdb::FunctionSymbol* target_symbol, jit_value_t lr,
|
||||||
|
bool tail);
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit b73375e72ef395800b8290bd02a3a0104b52a92c
|
Subproject commit d18139e9ed65cacce6db7d855212c9586e1f0361
|
Loading…
Reference in New Issue