Skip to content

Commit 53f23ac

Browse files
committed
Pass majority of rockwrestler tests
1 parent 281a5be commit 53f23ac

8 files changed

+68
-28
lines changed

src/jit/disassembler/alu_instructions.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,10 @@ mod alu_ops {
379379

380380
#[inline]
381381
pub fn smlalbb(opcode: u32, op: Op) -> InstInfo {
382-
let op0 = Reg::from(((opcode >> 16) & 0xF) as u8);
383-
let op1 = Reg::from((opcode & 0xF) as u8);
384-
let op2 = Reg::from(((opcode >> 8) & 0xF) as u8);
385-
let op3 = Reg::from(((opcode >> 12) & 0xF) as u8);
382+
let op0 = Reg::from(((opcode >> 12) & 0xF) as u8);
383+
let op1 = Reg::from(((opcode >> 16) & 0xF) as u8);
384+
let op2 = Reg::from((opcode & 0xF) as u8);
385+
let op3 = Reg::from(((opcode >> 8) & 0xF) as u8);
386386
InstInfo::new(
387387
opcode,
388388
op,
@@ -417,7 +417,7 @@ mod alu_ops {
417417
opcode,
418418
op,
419419
Operands::new_3(Operand::reg(op0), Operand::reg(op1), Operand::reg(op2)),
420-
reg_reserve!(op1, op2),
420+
reg_reserve!(op1, op2, Reg::CPSR),
421421
reg_reserve!(op0, Reg::CPSR),
422422
1,
423423
)

src/jit/disassembler/branch_instructions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mod branch_ops {
2727
Op::Blx,
2828
Operands::new_1(Operand::imm(op0 as u32)),
2929
reg_reserve!(),
30-
reg_reserve!(),
30+
reg_reserve!(Reg::LR, Reg::PC),
3131
1,
3232
)
3333
} else {
@@ -47,7 +47,7 @@ mod branch_ops {
4747
Op::Blx,
4848
Operands::new_1(Operand::imm(op0 as u32)),
4949
reg_reserve!(),
50-
reg_reserve!(Reg::PC),
50+
reg_reserve!(Reg::LR, Reg::PC),
5151
1,
5252
)
5353
} else {

src/jit/emitter/emit.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::jit::inst_branch_handler::branch_any_reg;
77
use crate::jit::inst_thread_regs_handler::{register_restore_spsr, restore_thumb_after_restore_spsr, set_pc_arm_mode, set_pc_thumb_mode};
88
use crate::jit::jit_asm::{debug_after_exec_op, JitAsm, JitRuntimeData};
99
use crate::jit::op::Op;
10-
use crate::jit::reg::Reg;
10+
use crate::jit::reg::{reg_reserve, Reg};
1111
use crate::jit::Cond;
1212
use crate::logging::debug_println;
1313
use crate::{DEBUG_LOG, IS_DEBUG};
@@ -127,23 +127,29 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
127127
block_asm.current_pc = start_pc + (((i - start_index) as u32) << pc_shift);
128128
self.jit_buf.debug_info.record_inst_offset(i, block_asm.get_cursor_offset() as usize);
129129

130-
if !self.jit_buf.insts[i].op.is_multiple_mem_transfer() {
130+
let inst = &self.jit_buf.insts[i];
131+
if inst.op.is_multiple_mem_transfer() {
132+
let op0 = inst.operands()[0].as_reg_no_shift().unwrap();
133+
let op1 = inst.operands()[1].as_reg_list().unwrap();
134+
let next_live_regs = self.analyzer.get_next_live_regs(basic_block_index, i);
135+
block_asm.alloc_guest_regs(reg_reserve!(op0), op1 & Reg::PC, next_live_regs);
136+
} else {
131137
self.emit_guest_regs_alloc(i, basic_block_index, block_asm);
132138
}
133139

134140
let inst = &self.jit_buf.insts[i];
135141
debug_println!("{:x}: block {basic_block_index}: emit {inst:?}", block_asm.current_pc);
136142

143+
// if block_asm.current_pc == 0x20076d4 {
144+
// block_asm.bkpt1(0);
145+
// }
146+
137147
let mut label = Label::new();
138148
let needs_cond_jump = !matches!(inst.op, Op::Clz | Op::Qadd | Op::Qsub | Op::Qdadd | Op::Qdsub) && !inst.op.is_alu() && !inst.op.is_mul();
139149
if inst.cond != Cond::AL && needs_cond_jump {
140150
block_asm.b3(!inst.cond, &mut label, BranchHint_kNear);
141151
}
142152

143-
// if block_asm.current_pc == 0x20046c4 {
144-
// block_asm.bkpt1(0);
145-
// }
146-
147153
if thumb {
148154
match inst.op {
149155
Op::BlSetupT => {}
@@ -163,10 +169,11 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
163169
Op::Mcr | Op::Mrc => self.emit_cp15(i, basic_block_index, block_asm),
164170
Op::MsrRc | Op::MsrIc | Op::MsrRs | Op::MsrIs => self.emit_msr(i, basic_block_index, block_asm),
165171
Op::MrsRc | Op::MrsRs => self.emit_mrs(i, block_asm),
166-
Op::BlxReg => self.emit_blx(i, basic_block_index, block_asm),
172+
Op::BlxReg => self.emit_blx_reg(i, basic_block_index, block_asm),
167173
Op::Bl => self.emit_bl(i, basic_block_index, block_asm),
168174
Op::B => self.emit_b(i, basic_block_index, block_asm),
169175
Op::Bx => self.emit_bx(i, basic_block_index, block_asm),
176+
Op::Blx => self.emit_blx(i, basic_block_index, block_asm),
170177
Op::Swi => self.emit_swi(i, basic_block_index, false, block_asm),
171178
Op::Swp | Op::Swpb => self.emit_swp(i, basic_block_index, block_asm),
172179
Op::Clz => self.emit_clz(i, block_asm),

src/jit/emitter/emit_alu.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::core::CpuType;
2+
use crate::core::CpuType::ARM9;
23
use crate::jit::assembler::block_asm::BlockAsm;
34
use crate::jit::assembler::vixl::{
45
vixl, MasmClz3, MasmMla5, MasmMlas5, MasmMul4, MasmMuls4, MasmQadd4, MasmQdadd4, MasmQdsub4, MasmQsub4, MasmSmlabb5, MasmSmlabt5, MasmSmlal5, MasmSmlalbb5, MasmSmlalbt5, MasmSmlals5,
@@ -128,6 +129,10 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
128129
}
129130

130131
pub fn emit_clz(&mut self, inst_index: usize, block_asm: &mut BlockAsm) {
132+
if CPU != ARM9 {
133+
return;
134+
}
135+
131136
let inst = &self.jit_buf.insts[inst_index];
132137

133138
let operands = inst.operands();
@@ -138,6 +143,10 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
138143
}
139144

140145
pub fn emit_q_op(&mut self, inst_index: usize, block_asm: &mut BlockAsm) {
146+
if CPU != ARM9 {
147+
return;
148+
}
149+
141150
let inst = &self.jit_buf.insts[inst_index];
142151

143152
let operands = inst.operands();
@@ -148,8 +157,8 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
148157
let func = match inst.op {
149158
Op::Qadd => <MacroAssembler as MasmQadd4<Cond, Reg, Reg, Reg>>::qadd4,
150159
Op::Qsub => <MacroAssembler as MasmQsub4<_, _, _, _>>::qsub4,
151-
Op::Qdadd => <MacroAssembler as MasmQdadd4<Cond, Reg, Reg, Reg>>::qdadd4,
152-
Op::Qdsub => <MacroAssembler as MasmQdsub4<Cond, Reg, Reg, Reg>>::qdsub4,
160+
Op::Qdadd => <MacroAssembler as MasmQdadd4<_, _, _, _>>::qdadd4,
161+
Op::Qdsub => <MacroAssembler as MasmQdsub4<_, _, _, _>>::qdsub4,
153162
_ => unreachable!(),
154163
};
155164

src/jit/emitter/emit_branch.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
268268
}
269269
}
270270

271-
pub fn emit_blx(&mut self, inst_index: usize, basic_block_index: usize, block_asm: &mut BlockAsm) {
271+
pub fn emit_blx_reg(&mut self, inst_index: usize, basic_block_index: usize, block_asm: &mut BlockAsm) {
272272
let inst = &self.jit_buf.insts[inst_index];
273273
let op0 = inst.operands()[0].as_reg_no_shift().unwrap();
274274
let op0_mapped = block_asm.get_guest_map(op0);
@@ -334,6 +334,27 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
334334
}
335335
}
336336

337+
pub fn emit_blx(&mut self, inst_index: usize, basic_block_index: usize, block_asm: &mut BlockAsm) {
338+
if CPU != ARM9 {
339+
return;
340+
}
341+
342+
let inst = &self.jit_buf.insts[inst_index];
343+
let relative_pc = inst.operands()[0].as_imm().unwrap() as i32 + 8;
344+
let target_pc = (block_asm.current_pc as i32 + relative_pc) as u32;
345+
346+
let pc_reg = block_asm.get_guest_map(Reg::PC);
347+
block_asm.ldr2(pc_reg, target_pc | 1);
348+
349+
let lr_reg = block_asm.get_guest_map(Reg::LR);
350+
let pc = block_asm.current_pc;
351+
block_asm.mov2(lr_reg, &(pc + 4).into());
352+
block_asm.add_dirty_guest_regs(reg_reserve!(Reg::LR, Reg::PC));
353+
block_asm.save_dirty_guest_regs(true, inst.cond == Cond::AL);
354+
355+
self.emit_branch_external_label(inst_index, basic_block_index, target_pc | 1, true, block_asm);
356+
}
357+
337358
extern "C" fn debug_branch_label(current_pc: u32, target_pc: u32) {
338359
branch_println!("{CPU:?} branch label from {current_pc:x} to {target_pc:x}")
339360
}

src/jit/emitter/emit_psr.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::core::CpuType;
2-
use crate::jit::assembler::block_asm::{BlockAsm, CPSR_TMP_REG};
3-
use crate::jit::assembler::vixl::vixl::{FlagsUpdate_DontCare, SpecialRegisterType_CPSR};
4-
use crate::jit::assembler::vixl::{MasmAnd3, MasmBic3, MasmMov4, MasmMrs2, MasmOrr3};
2+
use crate::jit::assembler::block_asm::{BlockAsm, CPSR_TMP_REG, GUEST_REGS_PTR_REG};
3+
use crate::jit::assembler::vixl::vixl::{FlagsUpdate_DontCare, MaskedSpecialRegisterType_CPSR_f, MemOperand, SpecialRegisterType_CPSR};
4+
use crate::jit::assembler::vixl::{MasmAnd3, MasmLdrh2, MasmMov4, MasmMrs2, MasmMsr2, MasmOrr3};
55
use crate::jit::inst_info::Operand;
66
use crate::jit::inst_thread_regs_handler::{register_set_cpsr_checked, register_set_spsr_checked};
77
use crate::jit::jit_asm::JitAsm;
@@ -33,6 +33,8 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
3333
block_asm.mov4(FlagsUpdate_DontCare, Cond::AL, Reg::R1, &flags.into());
3434
block_asm.call(func);
3535

36+
block_asm.msr2(MaskedSpecialRegisterType_CPSR_f.into(), &Reg::R0.into());
37+
3638
let next_live_regs = self.analyzer.get_next_live_regs(basic_block_index, inst_index);
3739
block_asm.restore_tmp_regs(next_live_regs);
3840

@@ -47,10 +49,9 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
4749

4850
match inst.op {
4951
Op::MrsRc => {
50-
block_asm.load_guest_reg(Reg::R1, Reg::CPSR);
52+
block_asm.ldrh2(Reg::R1, &MemOperand::reg_offset(GUEST_REGS_PTR_REG, Reg::CPSR as i32 * 4));
5153
block_asm.mrs2(CPSR_TMP_REG, SpecialRegisterType_CPSR.into());
52-
block_asm.bic3(Reg::R1, Reg::R1, &0xFF000000u32.into());
53-
block_asm.and3(CPSR_TMP_REG, CPSR_TMP_REG, &0xFF000000u32.into());
54+
block_asm.and3(CPSR_TMP_REG, CPSR_TMP_REG, &0xF8000000u32.into());
5455
block_asm.orr3(op0_mapped, Reg::R1, &CPSR_TMP_REG.into());
5556
}
5657
Op::MrsRs => block_asm.load_guest_reg(op0_mapped, Reg::SPSR),

src/jit/emitter/emit_transfer.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
166166

167167
pub fn emit_multiple_transfer(&mut self, inst_index: usize, basic_block_index: usize, block_asm: &mut BlockAsm) {
168168
let inst = &self.jit_buf.insts[inst_index];
169-
let next_live_regs = self.analyzer.get_next_live_regs(basic_block_index, inst_index);
170169

171170
let transfer = match inst.op {
172171
Op::Ldm(transfer) | Op::LdmT(transfer) | Op::Stm(transfer) | Op::StmT(transfer) => transfer,
@@ -176,8 +175,6 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
176175
let op0 = inst.operands()[0].as_reg_no_shift().unwrap();
177176
let mut op1 = inst.operands()[1].as_reg_list().unwrap();
178177

179-
block_asm.alloc_guest_regs(reg_reserve!(op0), op1 & Reg::PC, next_live_regs);
180-
181178
let op0_mapped = block_asm.get_guest_map(op0);
182179
let op1_len = op1.len();
183180

@@ -188,6 +185,8 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
188185
let fast_mem_start = block_asm.get_cursor_offset();
189186
block_asm.nop0();
190187
block_asm.mov4(FlagsUpdate_DontCare, Cond::AL, Reg::R0, &op0_mapped.into());
188+
block_asm.ldr2(Reg::R2, !0xF0000003);
189+
block_asm.and5(FlagsUpdate_DontCare, Cond::AL, Reg::R0, Reg::R0, &Reg::R2.into());
191190
block_asm.load_mmu_offset(Reg::R1);
192191
block_asm.add5(FlagsUpdate_DontCare, Cond::AL, Reg::R0, Reg::R0, &Reg::R1.into());
193192

@@ -297,6 +296,7 @@ impl<const CPU: CpuType> JitAsm<'_, CPU> {
297296
block_asm.call(func);
298297
}
299298

299+
let next_live_regs = self.analyzer.get_next_live_regs(basic_block_index, inst_index);
300300
block_asm.restore_tmp_regs(next_live_regs);
301301
block_asm.reload_active_guest_regs();
302302
}

src/jit/inst_thread_regs_handler.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
use crate::core::CpuType;
22
use crate::get_jit_asm_ptr;
33

4-
pub unsafe extern "C" fn register_set_cpsr_checked<const CPU: CpuType>(value: u32, flags: u8) {
4+
pub unsafe extern "C" fn register_set_cpsr_checked<const CPU: CpuType>(value: u32, flags: u8) -> u32 {
55
let asm = get_jit_asm_ptr::<CPU>();
66
(*asm).emu.thread_set_cpsr_with_flags(CPU, value, flags);
7+
(*asm).emu.thread[CPU].cpsr
78
}
89

9-
pub unsafe extern "C" fn register_set_spsr_checked<const CPU: CpuType>(value: u32, flags: u8) {
10+
pub unsafe extern "C" fn register_set_spsr_checked<const CPU: CpuType>(value: u32, flags: u8) -> u32 {
1011
let asm = get_jit_asm_ptr::<CPU>();
1112
(*asm).emu.thread_set_spsr_with_flags(CPU, value, flags);
13+
(*asm).emu.thread[CPU].cpsr
1214
}
1315

1416
pub unsafe extern "C" fn register_restore_spsr<const CPU: CpuType>() {

0 commit comments

Comments
 (0)