Skip to content

Commit 8ff8f10

Browse files
committed
WIP
1 parent 6fc7ebc commit 8ff8f10

File tree

5 files changed

+55
-26
lines changed

5 files changed

+55
-26
lines changed

src/jit/assembler/basic_block.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ impl BasicBlock {
338338
inst_opcodes.clear();
339339
inst.kind
340340
.emit_opcode(&mut inst_opcodes, opcodes.len(), &mut asm.buf.branch_placeholders, opcodes_offset, used_host_regs);
341+
for opcode in &mut inst_opcodes {
342+
*opcode = (*opcode & !(0xF << 28)) | ((inst.cond as u32) << 28);
343+
}
341344
opcodes.extend(&inst_opcodes);
342345
}
343346
opcodes

src/jit/assembler/block_asm.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub struct BlockAsm<'a> {
5656
tmp_shift_imm_reg: BlockReg,
5757
tmp_func_call_reg: BlockReg,
5858

59-
cond_block_end_label_stack: Vec<BlockLabel>,
59+
cond_block_end_label_stack: Vec<(BlockLabel, Cond, usize)>,
6060

6161
guest_reg_init_offset: Option<usize>,
6262
is_common_fun: bool,
@@ -377,7 +377,7 @@ impl<'a> BlockAsm<'a> {
377377
}
378378

379379
pub fn branch(&mut self, label: BlockLabel, cond: Cond) {
380-
self.insert_inst(BlockInstKind::Branch { label, block_index: 0, cond })
380+
self.insert_inst(BlockInst::new(cond, BlockInstKind::Branch { label, block_index: 0 }))
381381
}
382382

383383
pub fn save_context(&mut self) {
@@ -567,7 +567,7 @@ impl<'a> BlockAsm<'a> {
567567
}
568568
Some(label) => *label,
569569
};
570-
self.insert_inst(BlockInstKind::Branch { label, block_index: 0, cond });
570+
self.insert_inst(BlockInst::new(cond, BlockInstKind::Branch { label, block_index: 0 }));
571571
}
572572

573573
pub fn generic_guest_inst(&mut self, inst_info: &mut InstInfo) {
@@ -600,13 +600,21 @@ impl<'a> BlockAsm<'a> {
600600
if cond != Cond::AL {
601601
let label = self.new_label();
602602
self.branch(label, !cond);
603-
self.cond_block_end_label_stack.push(label);
603+
self.cond_block_end_label_stack.push((label, cond, self.buf.insts.len()));
604604
}
605605
}
606606

607607
pub fn end_cond_block(&mut self) {
608-
if let Some(label) = self.cond_block_end_label_stack.pop() {
609-
self.label(label);
608+
if let Some((label, cond, start_index)) = self.cond_block_end_label_stack.pop() {
609+
let cond_block_size = self.buf.insts.len() - start_index;
610+
let (_, outputs) = self.buf.insts[start_index].get_io();
611+
if cond_block_size == 1 && self.buf.insts[start_index].cond == Cond::AL && !outputs.contains(BlockReg::Fixed(Reg::CPSR)) && !outputs.contains(Reg::CPSR.into()) {
612+
self.buf.insts[start_index].cond = cond;
613+
// Remove the branch
614+
self.buf.insts.remove(start_index - 1);
615+
} else {
616+
self.label(label);
617+
}
610618
}
611619
}
612620

@@ -761,17 +769,22 @@ impl<'a> BlockAsm<'a> {
761769
// Link blocks
762770
for (i, basic_block) in basic_blocks.iter_mut().enumerate() {
763771
let last_inst_index = BlockInstList::deref(basic_block.block_entry_end).value;
772+
let cond = self.buf.insts[last_inst_index].cond;
764773
match &mut self.buf.insts[last_inst_index].kind {
765-
BlockInstKind::Branch { label, block_index, cond } => {
774+
BlockInstKind::Branch { label, block_index } => {
766775
let labelled_block_index = basic_block_label_mapping.get(&label.0).unwrap();
767776
basic_block.exit_blocks.push(*labelled_block_index);
768777
*block_index = *labelled_block_index;
769-
if *cond != Cond::AL && i + 1 < basic_blocks_len {
778+
if cond != Cond::AL && i + 1 < basic_blocks_len {
770779
basic_block.exit_blocks.push(i + 1);
771780
}
772781
}
773782
// Don't add exit when last command in basic block is a breakout
774-
BlockInstKind::Call { has_return: false, .. } | BlockInstKind::CallCommon { has_return: false, .. } | BlockInstKind::Epilogue { .. } => {}
783+
BlockInstKind::Call { has_return: false, .. } | BlockInstKind::CallCommon { has_return: false, .. } | BlockInstKind::Epilogue { .. } => {
784+
if cond != Cond::AL && i + 1 < basic_blocks_len {
785+
basic_block.exit_blocks.push(i + 1);
786+
}
787+
}
775788
_ if i + 1 < basic_blocks_len => basic_block.exit_blocks.push(i + 1),
776789
_ => {}
777790
}

src/jit/assembler/block_inst.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,30 @@ pub struct BranchEncoding {
7575

7676
#[derive(Clone)]
7777
pub struct BlockInst {
78+
pub cond: Cond,
7879
pub kind: BlockInstKind,
7980
io_cache: RefCell<Option<(BlockRegSet, BlockRegSet)>>,
8081
}
8182

8283
impl BlockInst {
83-
pub fn new(kind: BlockInstKind) -> Self {
84-
BlockInst { kind, io_cache: RefCell::new(None) }
84+
pub fn new(cond: Cond, kind: BlockInstKind) -> Self {
85+
BlockInst {
86+
cond,
87+
kind,
88+
io_cache: RefCell::new(None),
89+
}
8590
}
8691

8792
pub fn get_io(&self) -> (BlockRegSet, BlockRegSet) {
8893
let mut cached_io = self.io_cache.borrow_mut();
8994
match *cached_io {
9095
None => {
91-
let io = self.kind.get_io();
92-
*cached_io = Some(io);
93-
io
96+
let (mut inputs, outputs) = self.kind.get_io();
97+
if self.cond != Cond::AL {
98+
inputs.add_guests(outputs.get_guests());
99+
}
100+
*cached_io = Some((inputs, outputs));
101+
(inputs, outputs)
94102
}
95103
Some(cache) => cache,
96104
}
@@ -109,13 +117,13 @@ impl BlockInst {
109117

110118
impl From<BlockInstKind> for BlockInst {
111119
fn from(value: BlockInstKind) -> Self {
112-
BlockInst::new(value)
120+
BlockInst::new(Cond::AL, value)
113121
}
114122
}
115123

116124
impl Debug for BlockInst {
117125
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
118-
write!(f, "{:?}", self.kind)
126+
write!(f, "{:?} {:?}", self.cond, self.kind)
119127
}
120128
}
121129

@@ -186,7 +194,6 @@ pub enum BlockInstKind {
186194
Branch {
187195
label: BlockLabel,
188196
block_index: usize,
189-
cond: Cond,
190197
},
191198

192199
SaveContext {
@@ -679,10 +686,10 @@ impl BlockInstKind {
679686
}
680687
},
681688

682-
BlockInstKind::Branch { block_index, cond, .. } => {
689+
BlockInstKind::Branch { block_index, .. } => {
683690
// Encode label
684691
// Branch offset can only be figured out later
685-
opcodes.push(BranchEncoding::new(u26::new(*block_index as u32), false, false, u4::new(*cond as u8)).into());
692+
opcodes.push(BranchEncoding::new(u26::new(*block_index as u32), false, false, u4::new(Cond::AL as u8)).into());
686693
branch_placeholders.push(opcodes_offset + opcode_index);
687694
}
688695

@@ -860,7 +867,7 @@ impl Debug for BlockInstKind {
860867
};
861868
write!(f, "Label {label:?}{guest_pc}")
862869
}
863-
BlockInstKind::Branch { label, block_index, cond } => write!(f, "B{cond:?} {label:?}, block index: {block_index}"),
870+
BlockInstKind::Branch { label, block_index } => write!(f, "B {label:?}, block index: {block_index}"),
864871
BlockInstKind::SaveContext { .. } => write!(f, "SaveContext"),
865872
BlockInstKind::SaveReg { guest_reg, reg_mapped, .. } => write!(f, "SaveReg {guest_reg:?}, mapped: {reg_mapped:?}"),
866873
BlockInstKind::RestoreReg { guest_reg, reg_mapped, .. } => write!(f, "RestoreReg {guest_reg:?}, mapped: {reg_mapped:?}"),

src/jit/assembler/block_reg_set.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ impl BlockRegSet {
6464
(sum - (self.0 .0[0] & ((1 << FIXED_REGS_OVERFLOW) - 1)).count_ones()) as usize
6565
}
6666

67+
pub const fn add_guests(&mut self, reg_reserve: RegReserve) {
68+
self.0 .0[0] |= reg_reserve.0 << Reg::None as u8;
69+
let spilled_over_count = Reg::None as u8 * 2 - 32;
70+
self.0 .0[1] |= reg_reserve.0 >> (Reg::None as u8 - spilled_over_count);
71+
}
72+
6773
pub const fn remove_guests(&mut self, reg_reserve: RegReserve) {
6874
self.0 .0[0] &= !(reg_reserve.0 << Reg::None as u8);
6975
let spilled_over_count = Reg::None as u8 * 2 - 32;

src/jit/jit_asm.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(asm: &mut Jit
186186
}
187187

188188
let jit_entry = {
189-
// unsafe { BLOCK_LOG = guest_pc == 0x20026b4 };
189+
unsafe { BLOCK_LOG = guest_pc == 0x20cfd94 };
190190

191191
let mut block_asm = asm.new_block_asm(false);
192192

@@ -214,11 +214,11 @@ fn emit_code_block_internal<const CPU: CpuType, const THUMB: bool>(asm: &mut Jit
214214
asm.emit(&mut block_asm);
215215
}
216216

217-
if DEBUG_LOG {
218-
block_asm.save_context();
219-
block_asm.call2(debug_after_exec_op::<CPU> as *const (), asm.jit_buf.current_pc, asm.jit_buf.current_inst().opcode);
220-
block_asm.restore_reg(Reg::CPSR);
221-
}
217+
// if DEBUG_LOG {
218+
// block_asm.save_context();
219+
// block_asm.call2(debug_after_exec_op::<CPU> as *const (), asm.jit_buf.current_pc, asm.jit_buf.current_inst().opcode);
220+
// block_asm.restore_reg(Reg::CPSR);
221+
// }
222222
}
223223

224224
let opcodes_len = block_asm.emit_opcodes(guest_pc, THUMB);

0 commit comments

Comments
 (0)