Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Grarak committed Jan 8, 2025
1 parent 09c2e58 commit a7f1e83
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 47 deletions.
23 changes: 2 additions & 21 deletions src/jit/assembler/basic_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,29 +153,10 @@ impl BasicBlock {
BlockInstType::PadBlock(inner) => {
self.pad_label = Some((inner.label, inner.correction));
}
inst_type => {
_ => {
let (inputs, _) = buf.get_inst(i).get_io();
let inputs = inputs.get_guests();

if inputs.is_reserved(Reg::PC) {
let mut last_pc = last_pc + if thumb { 4 } else { 8 };
if thumb {
if let BlockInstType::Alu(inner) = inst_type {
if inner.thumb_pc_aligned {
last_pc &= !0x3;
}
}
} else if let BlockInstType::GenericGuest(inner) = inst_type {
// PC + 12 when ALU shift by register
if inner.inst_info.op.is_alu_reg_shift() && *inner.inst_info.operands().last().unwrap().as_reg().unwrap().0 == Reg::PC {
last_pc += 4;
}
}

self.inst_indices.push(buf.insts.len());
buf.insts.push(Alu::alu2(AluOp::Mov, [Reg::PC.into(), last_pc.into()], AluSetCond::None, false).into());
}

if inputs.is_reserved(Reg::CPSR) {
self.inst_indices.push(buf.insts.len());
buf.insts.push(
Expand Down Expand Up @@ -220,7 +201,7 @@ impl BasicBlock {
.into(),
);

buf.get_inst_mut(i).replace_input_regs(Reg::CPSR.into(), tmp_regs.host_cpsr_reg.into());
buf.get_inst_mut(i).replace_input_regs(Reg::CPSR.into(), tmp_regs.host_cpsr_reg);
}

if inputs.is_reserved(Reg::SPSR) {
Expand Down
61 changes: 38 additions & 23 deletions src/jit/assembler/block_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub struct BlockAsm {
cache: &'static mut BasicBlocksCache,
buf: &'static mut BlockAsmBuf,

is_thumb: bool,

any_reg_count: u16,
freed_any_regs: NoHashSet<u16>,
label_count: u16,
Expand All @@ -66,12 +68,14 @@ pub struct BlockAsm {

is_common_fun: bool,
host_sp_ptr: *mut usize,
block_start: usize,
inst_insert_index: Option<usize>,

last_pc: u32,
last_pc_thumb_aligned: bool,
last_pc_alu_shift: bool,
}

impl BlockAsm {
pub fn new(is_common_fun: bool, guest_regs_ptr: *mut u32, host_sp_ptr: *mut usize, cache: &'static mut BasicBlocksCache, buf: &'static mut BlockAsmBuf) -> Self {
pub fn new(is_common_fun: bool, guest_regs_ptr: *mut u32, host_sp_ptr: *mut usize, cache: &'static mut BasicBlocksCache, buf: &'static mut BlockAsmBuf, is_thumb: bool) -> Self {
buf.insts.clear();
buf.guest_branches_mapping.clear();

Expand All @@ -85,6 +89,8 @@ impl BlockAsm {
cache,
buf,

is_thumb,

// First couple any regs are reserved for guest mapping
any_reg_count: Reg::SPSR as u16 + 7,
freed_any_regs: NoHashSet::default(),
Expand All @@ -104,8 +110,10 @@ impl BlockAsm {

is_common_fun,
host_sp_ptr,
block_start: 0,
inst_insert_index: None,

last_pc: 0,
last_pc_thumb_aligned: false,
last_pc_alu_shift: false,
};

instance.insert_inst(Generic::Prologue);
Expand All @@ -130,26 +138,25 @@ impl BlockAsm {
instance.restore_reg(Reg::CPSR);
}

instance.block_start = instance.buf.insts.len();
instance
}

fn insert_inst(&mut self, inst: impl Into<BlockInst>) {
match self.inst_insert_index {
None => self.buf.insts.push(inst.into()),
Some(index) => {
self.buf.insts.insert(index, inst.into());
self.inst_insert_index = Some(index + 1);
let inst = inst.into();
let (inputs, _) = inst.get_io();
let guest_inputs = inputs.get_guests();
if guest_inputs.is_reserved(Reg::PC) {
let mut last_pc = self.last_pc + if self.is_thumb { 4 } else { 8 };
if self.last_pc_thumb_aligned {
last_pc &= !0x3;
} else if self.last_pc_alu_shift {
last_pc += 4;
}
self.buf.insts.push(Alu::alu2(AluOp::Mov, [Reg::PC.into(), last_pc.into()], AluSetCond::None, false).into());
}
}

pub fn set_insert_inst_index(&mut self, index: usize) {
self.inst_insert_index = Some(index);
}

pub fn reset_insert_inst_index(&mut self) {
self.inst_insert_index = None;
self.last_pc_alu_shift = false;
self.last_pc_thumb_aligned = false;
self.buf.insts.push(inst);
}

pub fn new_reg(&mut self) -> BlockReg {
Expand Down Expand Up @@ -246,18 +253,21 @@ impl BlockAsm {
fn add_op3(&mut self, op: AluOp, op0: BlockReg, op1: BlockReg, mut op2: BlockOperandShift, set_cond: AluSetCond, thumb_pc_aligned: bool) {
self.check_alu_imm_limit(&mut op2, true);
self.check_imm_shift_limit(&mut op2);
self.last_pc_thumb_aligned = thumb_pc_aligned;
self.insert_inst(Alu::alu3(op, [op0.into(), op1.into(), op2], set_cond, thumb_pc_aligned))
}

fn add_op2_op1(&mut self, op: AluOp, op1: BlockReg, mut op2: BlockOperandShift, set_cond: AluSetCond, thumb_pc_aligned: bool) {
self.check_alu_imm_limit(&mut op2, true);
self.check_imm_shift_limit(&mut op2);
self.last_pc_thumb_aligned = thumb_pc_aligned;
self.insert_inst(Alu::alu2(op, [op1.into(), op2], set_cond, thumb_pc_aligned))
}

fn add_op2_op0(&mut self, op: AluOp, op0: BlockReg, mut op2: BlockOperandShift, set_cond: AluSetCond, thumb_pc_aligned: bool) {
self.check_alu_imm_limit(&mut op2, op != AluOp::Mov);
self.check_imm_shift_limit(&mut op2);
self.last_pc_thumb_aligned = thumb_pc_aligned;
self.insert_inst(Alu::alu2(op, [op0.into(), op2], set_cond, thumb_pc_aligned))
}

Expand Down Expand Up @@ -626,6 +636,7 @@ impl BlockAsm {
}

pub fn guest_pc(&mut self, pc: u32) {
self.last_pc = pc;
self.insert_inst(GuestPc(pc));
}

Expand All @@ -650,6 +661,10 @@ impl BlockAsm {
}

pub fn generic_guest_inst(&mut self, inst_info: &mut InstInfo) {
// PC + 12 when ALU shift by register
if inst_info.op.is_alu_reg_shift() && *inst_info.operands().last().unwrap().as_reg().unwrap().0 == Reg::PC {
self.last_pc_alu_shift = true;
}
self.insert_inst(GenericGuest::new(inst_info));
}

Expand Down Expand Up @@ -715,7 +730,7 @@ impl BlockAsm {
}
}

fn assemble_basic_blocks(&mut self, block_start_pc: u32, thumb: bool) -> usize {
fn assemble_basic_blocks(&mut self, block_start_pc: u32) -> usize {
#[derive(Default)]
struct BasicBlockData {
start: u16,
Expand Down Expand Up @@ -896,7 +911,7 @@ impl BlockAsm {
_ => {}
}
}
basic_block.init_insts(self.buf, &self.tmp_regs, basic_block_start_pc, thumb);
basic_block.init_insts(self.buf, &self.tmp_regs, basic_block_start_pc, self.is_thumb);
}

for i in (0..basic_blocks_len).rev() {
Expand All @@ -922,8 +937,8 @@ impl BlockAsm {
basic_blocks_len
}

pub fn emit_opcodes(&mut self, block_start_pc: u32, thumb: bool) -> usize {
let basic_blocks_len = self.assemble_basic_blocks(block_start_pc, thumb);
pub fn emit_opcodes(&mut self, block_start_pc: u32) -> usize {
let basic_blocks_len = self.assemble_basic_blocks(block_start_pc);

if IS_DEBUG && !self.cache.basic_blocks[0].get_required_inputs().get_guests().is_empty() {
println!("inputs as requirement {:?}", self.cache.basic_blocks[0].get_required_inputs().get_guests());
Expand Down
2 changes: 1 addition & 1 deletion src/jit/emitter/thumb/emit_alu_thumb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
}

pub fn emit_cmp_h_thumb(&mut self, block_asm: &mut BlockAsm) {
let inst_info = &self.jit_buf.current_inst();
let inst_info = self.jit_buf.current_inst();

let operands = inst_info.operands();
let op1 = *operands[0].as_reg_no_shift().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions src/jit/jit_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ fn emit_code_block_internal<const CPU: CpuType>(asm: &mut JitAsm<CPU>, store_hos
let host_sp_ptr = ptr::addr_of_mut!(asm.runtime_data.host_sp);
let basic_blocks_cache = asm.basic_blocks_cache.get_mut();
let block_asm_buf = asm.block_asm_buf.get_mut();
let mut block_asm = unsafe { BlockAsm::new(false, guest_regs_ptr, host_sp_ptr, mem::transmute(basic_blocks_cache), mem::transmute(block_asm_buf)) };
let mut block_asm = unsafe { BlockAsm::new(false, guest_regs_ptr, host_sp_ptr, mem::transmute(basic_blocks_cache), mem::transmute(block_asm_buf), thumb) };

if DEBUG_LOG {
block_asm.call1(debug_enter_block::<CPU> as *const (), guest_pc | (thumb as u32));
Expand Down Expand Up @@ -286,7 +286,7 @@ fn emit_code_block_internal<const CPU: CpuType>(asm: &mut JitAsm<CPU>, store_hos

block_asm.epilogue();

let opcodes_len = block_asm.emit_opcodes(guest_pc, thumb);
let opcodes_len = block_asm.emit_opcodes(guest_pc);
let next_jit_entry = get_jit!(asm.emu).get_next_entry(opcodes_len);
let opcodes = block_asm.finalize(next_jit_entry);
if IS_DEBUG && unsafe { BLOCK_LOG } {
Expand Down

0 comments on commit a7f1e83

Please sign in to comment.