Skip to content

Commit 729116f

Browse files
committed
Create common functions for branching
1 parent 7b17e30 commit 729116f

File tree

16 files changed

+860
-447
lines changed

16 files changed

+860
-447
lines changed

src/bitset.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
use std::ops::{Add, AddAssign, BitAnd, BitXor, BitXorAssign, Not, Sub, SubAssign};
2+
3+
#[derive(Copy, Clone, Eq, PartialEq)]
4+
pub struct Bitset<const SIZE: usize>(pub [u32; SIZE]);
5+
6+
impl<const SIZE: usize> Bitset<SIZE> {
7+
pub const fn new() -> Self {
8+
Bitset([0; SIZE])
9+
}
10+
11+
fn _add(&mut self, bit: impl Into<usize>) {
12+
let bit = bit.into();
13+
let array_index = bit >> 5;
14+
let pos_index = bit & 31;
15+
self.0[array_index] |= 1 << pos_index;
16+
}
17+
18+
fn _sub(&mut self, bit: impl Into<usize>) {
19+
let bit = bit.into();
20+
let array_index = bit >> 5;
21+
let pos_index = bit & 31;
22+
self.0[array_index] &= !(1 << pos_index);
23+
}
24+
25+
pub fn contains(&self, bit: impl Into<usize>) -> bool {
26+
let bit = bit.into();
27+
let array_index = bit >> 5;
28+
let pos_index = bit & 31;
29+
self.0[array_index] & (1 << pos_index) != 0
30+
}
31+
32+
pub const fn len(&self) -> usize {
33+
let mut sum = 0;
34+
let mut i = 0;
35+
while i < self.0.len() {
36+
sum += self.0[i].count_ones();
37+
i += 1;
38+
}
39+
sum as usize
40+
}
41+
42+
pub const fn is_empty(&self) -> bool {
43+
self.len() == 0
44+
}
45+
}
46+
47+
impl<const SIZE: usize> Default for Bitset<SIZE> {
48+
fn default() -> Self {
49+
Bitset([0; SIZE])
50+
}
51+
}
52+
53+
impl<const SIZE: usize, T: Into<usize>> Add<T> for Bitset<SIZE> {
54+
type Output = Bitset<SIZE>;
55+
56+
fn add(mut self, rhs: T) -> Self::Output {
57+
self._add(rhs);
58+
self
59+
}
60+
}
61+
62+
impl<const SIZE: usize, T: Into<usize>> AddAssign<T> for Bitset<SIZE> {
63+
fn add_assign(&mut self, rhs: T) {
64+
self._add(rhs)
65+
}
66+
}
67+
68+
impl<const SIZE: usize, T: Into<usize>> Sub<T> for Bitset<SIZE> {
69+
type Output = Bitset<SIZE>;
70+
71+
fn sub(mut self, rhs: T) -> Self::Output {
72+
self._sub(rhs);
73+
self
74+
}
75+
}
76+
77+
impl<const SIZE: usize, T: Into<usize>> SubAssign<T> for Bitset<SIZE> {
78+
fn sub_assign(&mut self, rhs: T) {
79+
self._sub(rhs);
80+
}
81+
}
82+
83+
impl<const SIZE: usize> Add<Bitset<SIZE>> for Bitset<SIZE> {
84+
type Output = Bitset<SIZE>;
85+
86+
fn add(mut self, rhs: Bitset<SIZE>) -> Self::Output {
87+
for i in 0..self.0.len() {
88+
self.0[i] |= rhs.0[i];
89+
}
90+
self
91+
}
92+
}
93+
94+
impl<const SIZE: usize> AddAssign<Bitset<SIZE>> for Bitset<SIZE> {
95+
fn add_assign(&mut self, rhs: Bitset<SIZE>) {
96+
for i in 0..self.0.len() {
97+
self.0[i] |= rhs.0[i];
98+
}
99+
}
100+
}
101+
102+
impl<const SIZE: usize> Sub<Bitset<SIZE>> for Bitset<SIZE> {
103+
type Output = Bitset<SIZE>;
104+
105+
fn sub(mut self, rhs: Bitset<SIZE>) -> Self::Output {
106+
for i in 0..self.0.len() {
107+
self.0[i] &= !rhs.0[i];
108+
}
109+
self
110+
}
111+
}
112+
113+
impl<const SIZE: usize> SubAssign<Bitset<SIZE>> for Bitset<SIZE> {
114+
fn sub_assign(&mut self, rhs: Bitset<SIZE>) {
115+
for i in 0..self.0.len() {
116+
self.0[i] &= !rhs.0[i];
117+
}
118+
}
119+
}
120+
121+
impl<const SIZE: usize> BitAnd<Bitset<SIZE>> for Bitset<SIZE> {
122+
type Output = Bitset<SIZE>;
123+
124+
fn bitand(mut self, rhs: Bitset<SIZE>) -> Self::Output {
125+
for i in 0..self.0.len() {
126+
self.0[i] &= rhs.0[i];
127+
}
128+
self
129+
}
130+
}
131+
132+
impl<const SIZE: usize> BitXor<Bitset<SIZE>> for Bitset<SIZE> {
133+
type Output = Bitset<SIZE>;
134+
135+
fn bitxor(mut self, rhs: Bitset<SIZE>) -> Self::Output {
136+
for i in 0..self.0.len() {
137+
self.0[i] ^= rhs.0[i];
138+
}
139+
self
140+
}
141+
}
142+
143+
impl<const SIZE: usize> BitXorAssign for Bitset<SIZE> {
144+
fn bitxor_assign(&mut self, rhs: Self) {
145+
for i in 0..self.0.len() {
146+
self.0[i] ^= rhs.0[i];
147+
}
148+
}
149+
}
150+
151+
impl<const SIZE: usize> Not for Bitset<SIZE> {
152+
type Output = Bitset<SIZE>;
153+
154+
fn not(mut self) -> Self::Output {
155+
for i in 0..self.0.len() {
156+
self.0[i] = !self.0[i];
157+
}
158+
self
159+
}
160+
}

src/core/cpu_regs.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ impl Debug for InterruptFlags {
5959
}
6060
}
6161

62+
#[repr(C)]
6263
pub struct CpuRegs {
63-
cpu_type: CpuType,
64-
pub ime: u8,
6564
pub ie: u32,
6665
pub irf: u32,
66+
pub ime: u8,
6767
pub post_flg: u8,
6868
pub halt_cnt: u8,
6969
halt: u8,
70+
cpu_type: CpuType,
7071
pub bios_wait_flags: u32,
7172
}
7273

src/core/graphics/gpu_3d/registers_3d.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ impl Gpu3DRegisters {
560560
todo!("{:x}", entry.cmd);
561561
}
562562
}
563-
executed_cycles += 2;
563+
executed_cycles += 4;
564564

565565
self.cmd_pipe_size = 4 - ((self.cmd_pipe_size + param_count) & 1);
566566
if self.cmd_pipe_size as usize > self.cmd_fifo.len() {

src/core/thread_regs.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ pub struct Cpsr {
2222
pub n: bool,
2323
}
2424

25+
#[repr(C)]
2526
#[derive(Default)]
2627
pub struct UserRegs {
2728
pub gp_regs: [u32; 5],
2829
pub sp: u32,
2930
pub lr: u32,
3031
}
3132

33+
#[repr(C)]
3234
#[derive(Default)]
3335
pub struct FiqRegs {
3436
pub gp_regs: [u32; 5],
@@ -37,28 +39,30 @@ pub struct FiqRegs {
3739
pub spsr: u32,
3840
}
3941

42+
#[repr(C)]
4043
#[derive(Default)]
4144
pub struct OtherModeRegs {
4245
pub sp: u32,
4346
pub lr: u32,
4447
pub spsr: u32,
4548
}
4649

50+
#[repr(C, align(64))]
4751
pub struct ThreadRegs {
4852
pub gp_regs: [u32; 13],
4953
pub sp: u32,
5054
pub lr: u32,
5155
pub pc: u32,
5256
pub cpsr: u32,
5357
pub spsr: u32,
54-
is_user: bool,
5558
pub user: UserRegs,
5659
pub fiq: FiqRegs,
5760
pub svc: OtherModeRegs,
5861
pub abt: OtherModeRegs,
5962
pub irq: OtherModeRegs,
6063
pub und: OtherModeRegs,
6164
pub cpu: CpuRegs,
65+
is_user: bool,
6266
}
6367

6468
impl ThreadRegs {

src/jit/assembler/basic_block.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::jit::assembler::block_reg_set::BlockRegSet;
55
use crate::jit::assembler::{BlockAsmBuf, BlockInst};
66
use crate::jit::reg::{Reg, RegReserve};
77
use crate::jit::{MemoryAmount, ShiftType};
8-
use crate::utils::{BuildNoHasher, NoHashSet};
8+
use crate::IS_DEBUG;
99
use std::fmt::{Debug, Formatter};
1010

1111
pub struct BasicBlock {
@@ -18,8 +18,8 @@ pub struct BasicBlock {
1818
pub regs_live_ranges: Vec<BlockRegSet>,
1919
pub used_regs: Vec<BlockRegSet>,
2020

21-
pub enter_blocks: NoHashSet<usize>,
22-
pub exit_blocks: NoHashSet<usize>,
21+
pub enter_blocks: Vec<usize>,
22+
pub exit_blocks: Vec<usize>,
2323

2424
pub insts_link: BlockInstList,
2525

@@ -38,8 +38,8 @@ impl BasicBlock {
3838
regs_live_ranges: Vec::new(),
3939
used_regs: Vec::new(),
4040

41-
enter_blocks: NoHashSet::default(),
42-
exit_blocks: NoHashSet::with_capacity_and_hasher(2, BuildNoHasher),
41+
enter_blocks: Vec::new(),
42+
exit_blocks: Vec::with_capacity(2),
4343

4444
insts_link: BlockInstList::new(),
4545

@@ -63,11 +63,7 @@ impl BasicBlock {
6363
let mut add_inst = true;
6464
let mut guest_regs_outputs = RegReserve::new();
6565
match &mut asm.buf.insts[i] {
66-
BlockInst::Label { guest_pc, .. } => {
67-
if let Some(pc) = guest_pc {
68-
last_pc = *pc;
69-
}
70-
}
66+
BlockInst::Label { guest_pc: Some(pc), .. } => last_pc = *pc,
7167
BlockInst::GuestPc(pc) => last_pc = *pc,
7268
_ => match asm.buf.insts[i] {
7369
BlockInst::SaveContext {
@@ -130,6 +126,7 @@ impl BasicBlock {
130126
Reg::PC => {
131127
if !pc_initialized {
132128
pc_initialized = true;
129+
last_pc_reg = Reg::PC.into();
133130
self.insts_link.insert_end(asm.buf.insts.len());
134131
asm.buf.insts.push(BlockInst::Alu2Op0 {
135132
op: BlockAluOp::Mov,
@@ -242,6 +239,10 @@ impl BasicBlock {
242239
}
243240
}
244241

242+
if outputs.contains(Reg::PC.into()) {
243+
pc_initialized = false;
244+
}
245+
245246
guest_regs_outputs = outputs.get_guests();
246247
initialized_guest_regs += outputs.get_guests();
247248
}
@@ -376,13 +377,13 @@ impl BasicBlock {
376377
}
377378
}
378379

379-
pub fn emit_opcodes(&self, asm: &mut BlockAsm, branch_placeholders: &mut Vec<usize>, opcodes_offset: usize) -> Vec<u32> {
380+
pub fn emit_opcodes(&self, asm: &mut BlockAsm, branch_placeholders: &mut Vec<usize>, opcodes_offset: usize, used_host_regs: RegReserve) -> Vec<u32> {
380381
let mut opcodes = Vec::new();
381382
let mut inst_opcodes = Vec::new();
382383
for entry in self.insts_link.iter() {
383384
let inst = &mut asm.buf.insts[entry.value];
384385

385-
if unsafe { BLOCK_LOG } {
386+
if IS_DEBUG && unsafe { BLOCK_LOG } {
386387
match inst {
387388
BlockInst::GuestPc(pc) => {
388389
println!("(0x{:x}, 0x{pc:x}),", opcodes.len() + opcodes_offset);
@@ -397,7 +398,7 @@ impl BasicBlock {
397398
}
398399

399400
inst_opcodes.clear();
400-
inst.emit_opcode(&mut inst_opcodes, opcodes.len(), branch_placeholders, opcodes_offset);
401+
inst.emit_opcode(&mut inst_opcodes, opcodes.len(), branch_placeholders, opcodes_offset, used_host_regs);
401402
opcodes.extend(&inst_opcodes);
402403
}
403404
opcodes

0 commit comments

Comments
 (0)