Skip to content

Commit dc6146d

Browse files
committed
Link more blocks
1 parent b80f0dc commit dc6146d

File tree

5 files changed

+65
-43
lines changed

5 files changed

+65
-43
lines changed

src/core/hle/bios.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn interrupt<const CPU: CpuType>(emu: &mut Emu) {
5454
}
5555
}
5656

57-
pub fn uninterrupt<const CPU: CpuType>(emu: &mut Emu) {
57+
pub fn uninterrupt<const CPU: CpuType>(emu: &mut Emu) -> bool {
5858
debug_println!("{:?} uninterrupt", CPU);
5959

6060
if get_cpu_regs!(emu, CPU).bios_wait_flags != 0 {
@@ -68,12 +68,11 @@ pub fn uninterrupt<const CPU: CpuType>(emu: &mut Emu) {
6868
get_regs_mut!(emu, CPU).pc = get_regs!(emu, CPU).lr - 4;
6969

7070
let spsr = get_regs!(emu, CPU).spsr;
71-
if bool::from(Cpsr::from(spsr).thumb()) {
72-
get_regs_mut!(emu, CPU).pc |= 1;
73-
} else {
74-
get_regs_mut!(emu, CPU).pc &= !1;
75-
}
71+
72+
get_regs_mut!(emu, CPU).pc = (get_regs_mut!(emu, CPU).pc & !1) | Cpsr::from(spsr).thumb() as u32;
7673
get_regs_mut!(emu, CPU).set_cpsr::<false>(spsr, get_cm_mut!(emu));
74+
75+
!get_cpu_regs!(emu, CPU).is_halted()
7776
}
7877

7978
pub fn bit_unpack<const CPU: CpuType>(emu: &mut Emu) {

src/jit/emitter/emit_branch.rs

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
135135
if target_pc_reg == Reg::LR {
136136
self.emit_branch_return_stack_common(block_asm, target_pc_reg.into());
137137
} else {
138-
self.emit_branch_out_metadata(block_asm);
139-
block_asm.epilogue();
138+
self.emit_branch_reg_common(block_asm, target_pc_reg.into(), false);
140139
}
141140
}
142141

@@ -148,8 +147,6 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
148147
|asm, block_asm, runtime_data_addr_reg, breakout_label| {
149148
let return_stack_ptr_reg = block_asm.new_reg();
150149

151-
// block_asm.bkpt(1);
152-
153150
block_asm.load_u8(return_stack_ptr_reg, runtime_data_addr_reg, JitRuntimeData::get_return_stack_ptr_offset() as u32);
154151
block_asm.cmp(return_stack_ptr_reg, 0);
155152
block_asm.branch(breakout_label, Cond::EQ);
@@ -168,8 +165,9 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
168165
Self::emit_align_guest_pc(block_asm, target_pc_reg, aligned_target_pc_reg);
169166
block_asm.orr(aligned_target_pc_reg, aligned_target_pc_reg, thumb_bit_mask_reg);
170167

168+
let no_return_label = block_asm.new_label();
171169
block_asm.cmp(desired_lr_reg, aligned_target_pc_reg);
172-
block_asm.branch(breakout_label, Cond::NE);
170+
block_asm.branch(no_return_label, Cond::NE);
173171

174172
block_asm.store_u8(return_stack_ptr_reg, runtime_data_addr_reg, JitRuntimeData::get_return_stack_ptr_offset() as u32);
175173

@@ -181,11 +179,16 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
181179

182180
block_asm.epilogue_previous_block();
183181

184-
block_asm.free_reg(thumb_bit_mask_reg);
182+
block_asm.label(no_return_label);
183+
block_asm.mov(return_stack_ptr_reg, 0);
184+
block_asm.store_u8(return_stack_ptr_reg, runtime_data_addr_reg, JitRuntimeData::get_return_stack_ptr_offset() as u32);
185+
asm.emit_call_jit_addr(block_asm, aligned_target_pc_reg);
186+
185187
block_asm.free_reg(aligned_target_pc_reg);
186188
block_asm.free_reg(desired_lr_reg);
187189
block_asm.free_reg(return_stack_reg);
188190
block_asm.free_reg(return_stack_ptr_reg);
191+
block_asm.free_reg(thumb_bit_mask_reg);
189192
},
190193
|asm, block_asm| {
191194
asm.emit_branch_out_metadata(block_asm);
@@ -244,44 +247,18 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
244247
asm.emit_return_stack_write_desired_lr(block_asm, runtime_data_addr_reg);
245248
}
246249

247-
Self::emit_set_cpsr_thumb_bit(block_asm, target_pc_reg);
248-
249250
if DEBUG_LOG {
250-
// block_asm.call2(Self::debug_branch_reg as *const (), asm.jit_buf.current_pc, target_pc_reg);
251+
block_asm.call2(Self::debug_branch_reg as *const (), asm.jit_buf.current_pc, target_pc_reg);
251252
}
252253

253-
let aligned_target_reg = block_asm.new_reg();
254-
Self::emit_align_guest_pc(block_asm, target_pc_reg, aligned_target_reg);
255-
256-
let map_ptr = get_jit!(asm.emu).jit_memory_map.get_map_ptr::<CPU>();
257-
258-
let map_ptr_reg = block_asm.new_reg();
259-
let map_index_reg = block_asm.new_reg();
260-
let map_entry_base_ptr_reg = block_asm.new_reg();
261-
262-
block_asm.mov(map_ptr_reg, map_ptr as u32);
263-
block_asm.mov(map_index_reg, (aligned_target_reg.into(), ShiftType::Lsr, BlockOperand::from(jit_memory_map::BLOCK_SHIFT as u32 + 1)));
264-
block_asm.load_u32(map_entry_base_ptr_reg, map_ptr_reg, (map_index_reg.into(), ShiftType::Lsl, BlockOperand::from(2)));
265-
let block_size_mask_reg = map_index_reg;
266-
block_asm.mov(block_size_mask_reg, (jit_memory_map::BLOCK_SIZE as u32 - 1) << 2);
267-
block_asm.and(aligned_target_reg, block_size_mask_reg, (aligned_target_reg.into(), ShiftType::Lsl, BlockOperand::from(1)));
268-
269-
let entry_fn_reg = block_asm.new_reg();
270-
block_asm.load_u32(entry_fn_reg, map_entry_base_ptr_reg, aligned_target_reg);
254+
asm.emit_call_jit_addr(block_asm, target_pc_reg);
271255

272-
block_asm.call1(entry_fn_reg, 0);
273256
if has_lr_return {
274257
asm.emit_return_write_pre_cycle_count_sum(block_asm, runtime_data_addr_reg);
275258
block_asm.restore_reg(Reg::CPSR);
276259
} else {
277260
block_asm.epilogue_previous_block();
278261
}
279-
280-
block_asm.free_reg(entry_fn_reg);
281-
block_asm.free_reg(map_entry_base_ptr_reg);
282-
block_asm.free_reg(map_index_reg);
283-
block_asm.free_reg(map_ptr_reg);
284-
block_asm.free_reg(aligned_target_reg);
285262
},
286263
|asm, block_asm| {
287264
asm.emit_branch_out_metadata_no_count_cycles(block_asm);
@@ -290,6 +267,37 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
290267
);
291268
}
292269

270+
fn emit_call_jit_addr(&mut self, block_asm: &mut BlockAsm, target_pc_reg: BlockReg) {
271+
Self::emit_set_cpsr_thumb_bit(block_asm, target_pc_reg);
272+
273+
let aligned_target_reg = block_asm.new_reg();
274+
Self::emit_align_guest_pc(block_asm, target_pc_reg, aligned_target_reg);
275+
276+
let map_ptr = get_jit!(self.emu).jit_memory_map.get_map_ptr::<CPU>();
277+
278+
let map_ptr_reg = block_asm.new_reg();
279+
let map_index_reg = block_asm.new_reg();
280+
let map_entry_base_ptr_reg = block_asm.new_reg();
281+
282+
block_asm.mov(map_ptr_reg, map_ptr as u32);
283+
block_asm.mov(map_index_reg, (aligned_target_reg.into(), ShiftType::Lsr, BlockOperand::from(jit_memory_map::BLOCK_SHIFT as u32 + 1)));
284+
block_asm.load_u32(map_entry_base_ptr_reg, map_ptr_reg, (map_index_reg.into(), ShiftType::Lsl, BlockOperand::from(2)));
285+
let block_size_mask_reg = map_index_reg;
286+
block_asm.mov(block_size_mask_reg, (jit_memory_map::BLOCK_SIZE as u32 - 1) << 2);
287+
block_asm.and(aligned_target_reg, block_size_mask_reg, (aligned_target_reg.into(), ShiftType::Lsl, BlockOperand::from(1)));
288+
289+
let entry_fn_reg = block_asm.new_reg();
290+
block_asm.load_u32(entry_fn_reg, map_entry_base_ptr_reg, aligned_target_reg);
291+
292+
block_asm.call1(entry_fn_reg, 0);
293+
294+
block_asm.free_reg(entry_fn_reg);
295+
block_asm.free_reg(map_entry_base_ptr_reg);
296+
block_asm.free_reg(map_index_reg);
297+
block_asm.free_reg(map_ptr_reg);
298+
block_asm.free_reg(aligned_target_reg);
299+
}
300+
293301
pub fn emit_blx_label(&mut self, block_asm: &mut BlockAsm) {
294302
if CPU != ARM9 {
295303
return;

src/jit/emitter/emit_unknown.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
use crate::core::CpuType;
22
use crate::jit::assembler::block_asm::BlockAsm;
3+
use crate::jit::assembler::BlockReg;
34
use crate::jit::inst_exception_handler::bios_uninterrupt;
45
use crate::jit::jit_asm::JitAsm;
6+
use crate::jit::reg::Reg;
7+
use crate::jit::Cond;
58

69
impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
710
pub fn emit_unknown(&mut self, block_asm: &mut BlockAsm) {
811
// 0xEC000000 magic number to call finish bios hle interrupt
912
if self.jit_buf.current_inst().opcode == 0xEC000000 {
1013
block_asm.save_context();
14+
// Returns true if CPU is unhalted
1115
block_asm.call(bios_uninterrupt::<CPU> as *const ());
16+
17+
let breakout_label = block_asm.new_label();
18+
block_asm.cmp(BlockReg::Fixed(Reg::R0), 0);
19+
block_asm.branch(breakout_label, Cond::EQ);
20+
21+
let target_pc_reg = block_asm.new_reg();
22+
block_asm.load_u32(target_pc_reg, block_asm.thread_regs_addr_reg, Reg::PC as u32 * 4);
23+
self.emit_branch_reg_common(block_asm, target_pc_reg, false);
24+
block_asm.free_reg(target_pc_reg);
25+
26+
block_asm.label(breakout_label);
1227
self.emit_branch_out_metadata(block_asm);
1328
block_asm.epilogue();
1429
}

src/jit/emitter/thumb/emit_branch_thumb.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
7373
if target_pc_reg == Reg::LR {
7474
self.emit_branch_return_stack_common(block_asm, target_pc_reg.into());
7575
} else {
76-
self.emit_branch_out_metadata(block_asm);
77-
block_asm.epilogue();
76+
self.emit_branch_reg_common(block_asm, target_pc_reg.into(), false);
7877
}
7978
}
8079

src/jit/inst_exception_handler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ pub unsafe extern "C" fn exception_handler<const CPU: CpuType, const THUMB: bool
1313
}
1414
}
1515

16-
pub unsafe extern "C" fn bios_uninterrupt<const CPU: CpuType>() {
16+
pub unsafe extern "C" fn bios_uninterrupt<const CPU: CpuType>() -> bool {
1717
let asm = get_jit_asm_ptr::<CPU>();
18+
(*asm).runtime_data.return_stack_ptr = 0;
1819
bios::uninterrupt::<CPU>((*asm).emu)
1920
}

0 commit comments

Comments
 (0)