Optimization: Make RSB a ring buffer instead of a stack
This commit is contained in:
parent
7d7ac0af71
commit
0ebb572e2d
2 changed files with 23 additions and 11 deletions
|
@ -343,23 +343,35 @@ void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) {
|
|||
ASSERT(inst->GetArg(0).IsImmediate());
|
||||
u64 imm64 = inst->GetArg(0).GetU64();
|
||||
|
||||
X64Reg tmp = reg_alloc.ScratchRegister({HostLoc::RCX});
|
||||
X64Reg rsb_index = reg_alloc.ScratchRegister(any_gpr);
|
||||
X64Reg code_ptr_reg = reg_alloc.ScratchRegister({HostLoc::RCX});
|
||||
X64Reg loc_desc_reg = reg_alloc.ScratchRegister(any_gpr);
|
||||
X64Reg index_reg = reg_alloc.ScratchRegister(any_gpr);
|
||||
u64 code_ptr = unique_hash_to_code_ptr.find(imm64) != unique_hash_to_code_ptr.end()
|
||||
? u64(unique_hash_to_code_ptr[imm64])
|
||||
: u64(code->GetReturnFromRunCodeAddress());
|
||||
|
||||
code->MOV(32, R(rsb_index), MDisp(R15, offsetof(JitState, rsb_ptr)));
|
||||
code->AND(32, R(rsb_index), Imm32(u32(JitState::RSBSize - 1)));
|
||||
code->MOV(64, R(tmp), Imm64(imm64));
|
||||
code->MOV(64, MComplex(R15, rsb_index, SCALE_1, offsetof(JitState, rsb_location_descriptors)), R(tmp));
|
||||
code->MOV(32, R(index_reg), MDisp(R15, offsetof(JitState, rsb_ptr)));
|
||||
code->AND(32, R(index_reg), Imm32(JitState::RSBSize - 1));
|
||||
|
||||
code->MOV(64, R(loc_desc_reg), Imm64(imm64));
|
||||
CodePtr patch_location = code->GetCodePtr();
|
||||
patch_unique_hash_locations[imm64].emplace_back(patch_location);
|
||||
code->MOV(64, R(tmp), Imm64(code_ptr)); // This line has to match up with EmitX64::Patch.
|
||||
code->MOV(64, R(code_ptr_reg), Imm64(code_ptr)); // This line has to match up with EmitX64::Patch.
|
||||
ASSERT((code->GetCodePtr() - patch_location) == 10);
|
||||
code->MOV(64, MComplex(R15, rsb_index, SCALE_1, offsetof(JitState, rsb_codeptrs)), R(tmp));
|
||||
code->ADD(32, R(rsb_index), Imm32(1));
|
||||
code->MOV(32, MDisp(R15, offsetof(JitState, rsb_ptr)), R(rsb_index));
|
||||
|
||||
std::vector<FixupBranch> fixups;
|
||||
fixups.reserve(JitState::RSBSize);
|
||||
for (size_t i = 0; i < JitState::RSBSize; ++i) {
|
||||
code->CMP(64, R(loc_desc_reg), MDisp(R15, int(offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64))));
|
||||
fixups.push_back(code->J_CC(CC_E));
|
||||
}
|
||||
|
||||
code->MOV(32, MDisp(R15, offsetof(JitState, rsb_ptr)), R(index_reg));
|
||||
code->MOV(64, MComplex(R15, index_reg, SCALE_8, offsetof(JitState, rsb_location_descriptors)), R(loc_desc_reg));
|
||||
code->MOV(64, MComplex(R15, index_reg, SCALE_8, offsetof(JitState, rsb_codeptrs)), R(code_ptr_reg));
|
||||
for (auto f : fixups) {
|
||||
code->SetJumpTarget(f);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitX64::EmitGetCarryFromOp(IR::Block&, IR::Inst*) {
|
||||
|
|
|
@ -39,7 +39,7 @@ struct JitState {
|
|||
u32 exclusive_state = 0;
|
||||
u32 exclusive_address = 0;
|
||||
|
||||
static constexpr size_t RSBSize = 8; // MUST be a power of 2.ss
|
||||
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
|
||||
u32 rsb_ptr = 0;
|
||||
std::array<u64, RSBSize> rsb_location_descriptors;
|
||||
std::array<u64, RSBSize> rsb_codeptrs;
|
||||
|
|
Loading…
Reference in a new issue