Skip to content

Commit c49bf39

Browse files
committed
Inline cycle flushes
1 parent 54de332 commit c49bf39

File tree

4 files changed

+85
-39
lines changed

4 files changed

+85
-39
lines changed

src/jit/emitter/emit.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::jit::inst_threag_regs_handler::{register_restore_spsr, restore_thumb_
55
use crate::jit::jit_asm::{JitAsm, JitRuntimeData};
66
use crate::jit::op::Op;
77
use crate::jit::reg::Reg;
8-
use crate::jit::MemoryAmount;
8+
use crate::jit::{Cond, MemoryAmount};
99
use crate::DEBUG_LOG_BRANCH_OUT;
1010

1111
impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
@@ -98,4 +98,72 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
9898
pub fn emit_branch_out_metadata_with_idle_loop(&mut self, block_asm: &mut BlockAsm) {
9999
self._emit_branch_out_metadata(block_asm, true)
100100
}
101+
102+
pub fn emit_flush_cycles<ContinueFn: Fn(&mut Self, &mut BlockAsm), BreakoutFn: Fn(&mut Self, &mut BlockAsm)>(
103+
&mut self,
104+
block_asm: &mut BlockAsm,
105+
target_pre_cycle_count_sum: u16,
106+
continue_fn: ContinueFn,
107+
breakout_fn: BreakoutFn,
108+
) {
109+
let runtime_data_addr_reg = block_asm.new_reg();
110+
block_asm.mov(runtime_data_addr_reg, self.runtime_data.get_addr() as u32);
111+
112+
let accumulated_cycles_reg = block_asm.new_reg();
113+
block_asm.transfer_read(
114+
accumulated_cycles_reg,
115+
runtime_data_addr_reg,
116+
JitRuntimeData::get_accumulated_cycles_offset() as u32,
117+
false,
118+
MemoryAmount::Half,
119+
);
120+
121+
let pre_cycle_count_sum_reg = block_asm.new_reg();
122+
block_asm.transfer_read(
123+
pre_cycle_count_sum_reg,
124+
runtime_data_addr_reg,
125+
JitRuntimeData::get_pre_cycle_count_sum_offset() as u32,
126+
false,
127+
MemoryAmount::Half,
128+
);
129+
130+
let total_cycles_reg = block_asm.new_reg();
131+
// +2 for branching
132+
block_asm.add(total_cycles_reg, accumulated_cycles_reg, self.jit_buf.insts_cycle_counts[self.jit_buf.current_index] as u32 + 2);
133+
block_asm.sub(total_cycles_reg, total_cycles_reg, pre_cycle_count_sum_reg);
134+
135+
const MAX_LOOP_CYCLE_COUNT: u32 = 200;
136+
block_asm.cmp(total_cycles_reg, MAX_LOOP_CYCLE_COUNT - 1);
137+
138+
let breakout_label = block_asm.new_label();
139+
block_asm.branch(breakout_label, Cond::HI);
140+
141+
block_asm.transfer_write(
142+
total_cycles_reg,
143+
runtime_data_addr_reg,
144+
JitRuntimeData::get_accumulated_cycles_offset() as u32,
145+
false,
146+
MemoryAmount::Half,
147+
);
148+
149+
let target_pre_cycle_count_sum_reg = block_asm.new_reg();
150+
block_asm.mov(target_pre_cycle_count_sum_reg, target_pre_cycle_count_sum as u32);
151+
block_asm.transfer_write(
152+
target_pre_cycle_count_sum_reg,
153+
runtime_data_addr_reg,
154+
JitRuntimeData::get_pre_cycle_count_sum_offset() as u32,
155+
false,
156+
MemoryAmount::Half,
157+
);
158+
continue_fn(self, block_asm);
159+
160+
block_asm.label(breakout_label);
161+
breakout_fn(self, block_asm);
162+
163+
block_asm.free_reg(target_pre_cycle_count_sum_reg);
164+
block_asm.free_reg(total_cycles_reg);
165+
block_asm.free_reg(pre_cycle_count_sum_reg);
166+
block_asm.free_reg(accumulated_cycles_reg);
167+
block_asm.free_reg(runtime_data_addr_reg);
168+
}
101169
}

src/jit/emitter/emit_branch.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::core::CpuType;
22
use crate::core::CpuType::ARM9;
33
use crate::jit::assembler::block_asm::BlockAsm;
4-
use crate::jit::assembler::BlockReg;
5-
use crate::jit::inst_branch_handler::branch_label_flush_cycles;
64
use crate::jit::inst_info::InstInfo;
75
use crate::jit::jit_asm::JitAsm;
86
use crate::jit::op::Op;
@@ -79,30 +77,29 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
7977
block_asm.save_context();
8078
};
8179

82-
let branch_info = Self::analyze_branch_label::<THUMB>(&self.jit_buf.insts, self.jit_buf.current_index, self.jit_buf.current_inst().cond, self.jit_buf.current_pc, target_pc);
80+
let branch_info = Self::analyze_branch_label::<THUMB>(&self.jit_buf.insts, self.jit_buf.current_index, cond, self.jit_buf.current_pc, target_pc);
8381

8482
if let JitBranchInfo::Local(target_index) = branch_info {
85-
let current_total_cycles = self.jit_buf.insts_cycle_counts[self.jit_buf.current_index];
8683
let target_pre_cycle_count_sum = if target_index == 0 { 0 } else { self.jit_buf.insts_cycle_counts[target_index] };
8784

8885
let backed_up_cpsr_reg = block_asm.new_reg();
8986
block_asm.mrs_cpsr(backed_up_cpsr_reg);
9087

91-
block_asm.call2(branch_label_flush_cycles::<CPU> as *const (), current_total_cycles as u32, target_pre_cycle_count_sum as u32);
92-
block_asm.cmp(BlockReg::Fixed(Reg::R0), 1);
93-
94-
let breakout_label = block_asm.new_label();
95-
block_asm.branch(breakout_label, Cond::EQ);
96-
97-
block_asm.msr_cpsr(backed_up_cpsr_reg);
98-
block_asm.guest_branch(Cond::AL, target_pc);
99-
100-
block_asm.label(breakout_label);
101-
block_asm.msr_cpsr(backed_up_cpsr_reg);
102-
103-
commit_target_pc(block_asm);
104-
self.emit_branch_out_metadata(block_asm);
105-
block_asm.epilogue();
88+
self.emit_flush_cycles(
89+
block_asm,
90+
target_pre_cycle_count_sum,
91+
|_, block_asm| {
92+
block_asm.msr_cpsr(backed_up_cpsr_reg);
93+
block_asm.guest_branch(Cond::AL, target_pc);
94+
},
95+
|asm, block_asm| {
96+
block_asm.msr_cpsr(backed_up_cpsr_reg);
97+
98+
commit_target_pc(block_asm);
99+
asm.emit_branch_out_metadata(block_asm);
100+
block_asm.epilogue();
101+
},
102+
);
106103

107104
block_asm.free_reg(backed_up_cpsr_reg);
108105
return;

src/jit/inst_branch_handler.rs

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/jit/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ pub mod jit_asm;
1616
pub mod jit_memory;
1717
pub mod op;
1818
pub mod reg;
19-
mod inst_branch_handler;
2019

2120
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2221
#[repr(u8)]

0 commit comments

Comments
 (0)