Skip to content

Commit 501aacd

Browse files
committed
WIP
1 parent 8bd4f89 commit 501aacd

File tree

6 files changed

+63
-14
lines changed

6 files changed

+63
-14
lines changed

src/jit/emitter/emit.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::core::CpuType;
22
use crate::core::CpuType::ARM7;
33
use crate::jit::assembler::block_asm::BlockAsm;
4+
use crate::jit::assembler::{BlockLabel, BlockReg};
45
use crate::jit::inst_threag_regs_handler::{register_restore_spsr, restore_thumb_after_restore_spsr, set_pc_arm_mode};
56
use crate::jit::jit_asm::{JitAsm, JitRuntimeData};
67
use crate::jit::op::Op;
@@ -18,7 +19,8 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
1819
block_asm.start_cond_block(cond);
1920
match op {
2021
Op::B | Op::Bl => self.emit_branch_label(block_asm),
21-
Op::Bx | Op::BlxReg => self.emit_branch_reg(block_asm),
22+
Op::Bx => self.emit_bx(block_asm),
23+
Op::BlxReg => self.emit_blx(block_asm),
2224
Op::Blx => self.emit_blx_label(block_asm),
2325
Op::Mcr | Op::Mrc => self.emit_cp15(block_asm),
2426
Op::MsrRc | Op::MsrIc | Op::MsrRs | Op::MsrIs => self.emit_msr(block_asm),
@@ -99,7 +101,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
99101
self._emit_branch_out_metadata(block_asm, true)
100102
}
101103

102-
pub fn emit_flush_cycles<ContinueFn: Fn(&mut Self, &mut BlockAsm), BreakoutFn: Fn(&mut Self, &mut BlockAsm)>(
104+
pub fn emit_flush_cycles<ContinueFn: Fn(&mut Self, &mut BlockAsm, BlockLabel, BlockReg), BreakoutFn: Fn(&mut Self, &mut BlockAsm)>(
103105
&mut self,
104106
block_asm: &mut BlockAsm,
105107
target_pre_cycle_count_sum: u16,
@@ -155,7 +157,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
155157
false,
156158
MemoryAmount::Half,
157159
);
158-
continue_fn(self, block_asm);
160+
continue_fn(self, block_asm, breakout_label, runtime_data_addr_reg);
159161

160162
block_asm.label(breakout_label);
161163
breakout_fn(self, block_asm);

src/jit/emitter/emit_branch.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
8080
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);
8181

8282
if let JitBranchInfo::Local(target_index) = branch_info {
83-
let target_pre_cycle_count_sum = if target_index == 0 { 0 } else { self.jit_buf.insts_cycle_counts[target_index] };
83+
let target_pre_cycle_count_sum = self.jit_buf.insts_cycle_counts[target_index] - self.jit_buf.insts[target_index].cycle as u16;
8484

8585
let backed_up_cpsr_reg = block_asm.new_reg();
8686
block_asm.mrs_cpsr(backed_up_cpsr_reg);
8787

8888
self.emit_flush_cycles(
8989
block_asm,
9090
target_pre_cycle_count_sum,
91-
|_, block_asm| {
91+
|_, block_asm, _, _| {
9292
block_asm.msr_cpsr(backed_up_cpsr_reg);
9393
block_asm.guest_branch(Cond::AL, target_pc);
9494
},
@@ -113,19 +113,37 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
113113
block_asm.epilogue();
114114
}
115115

116-
pub fn emit_branch_reg(&mut self, block_asm: &mut BlockAsm) {
116+
pub fn emit_bx(&mut self, block_asm: &mut BlockAsm) {
117117
let inst_info = self.jit_buf.current_inst();
118118
let branch_to = *inst_info.operands()[0].as_reg_no_shift().unwrap();
119119

120-
if inst_info.op == Op::BlxReg {
121-
block_asm.mov(Reg::LR, self.jit_buf.current_pc + 4);
122-
}
123120
block_asm.mov(Reg::PC, branch_to);
124121
block_asm.save_context();
125122
self.emit_branch_out_metadata(block_asm);
126123
block_asm.epilogue();
127124
}
128125

126+
pub fn emit_blx(&mut self, block_asm: &mut BlockAsm) {
127+
let inst_info = self.jit_buf.current_inst();
128+
let branch_to = *inst_info.operands()[0].as_reg_no_shift().unwrap();
129+
130+
block_asm.mov(Reg::LR, self.jit_buf.current_pc + 4);
131+
block_asm.mov(Reg::PC, branch_to);
132+
block_asm.save_context();
133+
134+
self.emit_flush_cycles(
135+
block_asm,
136+
0,
137+
|asm, block_asm, breakout_label, runtime_data_addr_reg| {
138+
139+
},
140+
|asm, block_asm| {
141+
asm.emit_branch_out_metadata(block_asm);
142+
block_asm.epilogue();
143+
},
144+
);
145+
}
146+
129147
pub fn emit_blx_label(&mut self, block_asm: &mut BlockAsm) {
130148
if CPU != ARM9 {
131149
return;

src/jit/inst_branch_handler.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use crate::core::CpuType;
2+
use crate::get_jit_asm_ptr;
3+
4+
pub unsafe extern "C" fn block_link<const CPU: CpuType>(total_cycles: u16) {
5+
let asm = get_jit_asm_ptr::<CPU>();
6+
let runtime_data = &mut (*asm).runtime_data;
7+
runtime_data.block_link_stack
8+
}

src/jit/jit_asm.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,21 @@ impl JitBuf {
4545
}
4646
}
4747

48+
#[derive(Copy, Clone, Default)]
49+
pub struct JitBlockLinkData {
50+
pub desired_lr: u32,
51+
pub return_pre_cycle_count_sum: u16,
52+
}
53+
4854
#[repr(C)]
4955
pub struct JitRuntimeData {
5056
pub branch_out_pc: u32,
5157
pub branch_out_total_cycles: u16,
5258
pub pre_cycle_count_sum: u16,
5359
pub accumulated_cycles: u16,
5460
pub idle_loop: bool,
61+
pub block_link_ptr: u8,
62+
pub block_link_stack: [JitBlockLinkData; 32],
5563
}
5664

5765
impl JitRuntimeData {
@@ -62,16 +70,22 @@ impl JitRuntimeData {
6270
pre_cycle_count_sum: 0,
6371
accumulated_cycles: 0,
6472
idle_loop: false,
73+
block_link_ptr: 0,
74+
block_link_stack: [JitBlockLinkData::default(); 32],
6575
};
76+
6677
let branch_out_pc_ptr = ptr::addr_of!(instance.branch_out_pc) as usize;
6778
let branch_out_total_cycles_ptr = ptr::addr_of!(instance.branch_out_total_cycles) as usize;
6879
let pre_cycle_count_sum_ptr = ptr::addr_of!(instance.pre_cycle_count_sum) as usize;
6980
let accumulated_cycles_ptr = ptr::addr_of!(instance.accumulated_cycles) as usize;
7081
let idle_loop_ptr = ptr::addr_of!(instance.idle_loop) as usize;
82+
let block_link_ptr_ptr = ptr::addr_of!(instance.block_link_ptr) as usize;
83+
7184
assert_eq!(branch_out_total_cycles_ptr - branch_out_pc_ptr, Self::get_out_total_cycles_offset() as usize);
7285
assert_eq!(pre_cycle_count_sum_ptr - branch_out_pc_ptr, Self::get_pre_cycle_count_sum_offset() as usize);
7386
assert_eq!(accumulated_cycles_ptr - branch_out_pc_ptr, Self::get_accumulated_cycles_offset() as usize);
7487
assert_eq!(idle_loop_ptr - branch_out_pc_ptr, Self::get_idle_loop_offset() as usize);
88+
assert_eq!(block_link_ptr_ptr - branch_out_pc_ptr, Self::get_block_link_ptr_offset() as usize);
7589
instance
7690
}
7791

@@ -98,6 +112,10 @@ impl JitRuntimeData {
98112
pub const fn get_idle_loop_offset() -> u8 {
99113
Self::get_accumulated_cycles_offset() + 2
100114
}
115+
116+
pub const fn get_block_link_ptr_offset() -> u8 {
117+
Self::get_idle_loop_offset() + 1
118+
}
101119
}
102120

103121
pub extern "C" fn emit_code_block<const CPU: CpuType>() {
@@ -136,20 +154,20 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(guest_pc: u32
136154
assert!(asm.jit_buf.insts_cycle_counts.len() <= u16::MAX as usize, "{CPU:?} {guest_pc:x} {inst_info:?}")
137155
}
138156

139-
// let is_unreturnable_branch = !inst_info.out_regs.is_reserved(Reg::LR) && inst_info.is_uncond_branch() && !inst_info.op.is_labelled_branch();
140-
let is_uncond_branch = inst_info.is_uncond_branch();
157+
let is_unreturnable_branch = !inst_info.out_regs.is_reserved(Reg::LR) && inst_info.is_uncond_branch() && !inst_info.op.is_labelled_branch();
158+
// let is_uncond_branch = inst_info.is_uncond_branch();
141159
let is_unknown = inst_info.op == Op::UnkArm || inst_info.op == Op::UnkThumb;
142160

143161
asm.jit_buf.insts.push(inst_info);
144162

145163
index += if THUMB { 2 } else { 4 };
146-
if is_uncond_branch || is_unknown {
164+
if is_unreturnable_branch || is_unknown {
147165
break;
148166
}
149167
}
150168
}
151169

152-
// unsafe { BLOCK_LOG = true };
170+
unsafe { BLOCK_LOG = true };
153171

154172
let thread_regs = get_regs!(asm.emu, CPU);
155173
let mut block_asm = unsafe { (*asm.block_asm_buf.get()).new_asm(thread_regs, ptr::addr_of_mut!(asm.host_sp) as _) };
@@ -177,6 +195,7 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(guest_pc: u32
177195
for &opcode in &opcodes {
178196
println!("0x{opcode:x},");
179197
}
198+
todo!()
180199
}
181200
let insert_entry = get_jit_mut!(asm.emu).insert_block::<CPU>(&opcodes, guest_pc);
182201
let jit_entry: extern "C" fn() = unsafe { mem::transmute(insert_entry) };
@@ -210,6 +229,7 @@ fn execute_internal<const CPU: CpuType>(guest_pc: u32) -> u16 {
210229
}
211230
asm.runtime_data.pre_cycle_count_sum = 0;
212231
asm.runtime_data.accumulated_cycles = 0;
232+
asm.runtime_data.block_link_ptr = 0;
213233
get_regs_mut!(asm.emu, CPU).cycle_correction = 0;
214234

215235
jit_entry();

src/jit/jit_memory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl JitMemory {
154154
}
155155

156156
fn insert(&mut self, opcodes: &[u32]) -> (usize, usize) {
157-
let aligned_size = utils::align_up(opcodes.len() * size_of::<u32>(), *PAGE_SIZE);
157+
let aligned_size = utils::align_up(size_of_val(opcodes), *PAGE_SIZE);
158158
let allocated_offset_addr = self.allocate_block(aligned_size);
159159

160160
utils::write_to_mem_slice(&mut self.mem, allocated_offset_addr, opcodes);

src/jit/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub mod jit_memory;
1717
pub mod op;
1818
pub mod reg;
1919
mod jit_memory_map;
20+
mod inst_branch_handler;
2021

2122
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2223
#[repr(u8)]

0 commit comments

Comments
 (0)