Skip to content

Commit 46782a9

Browse files
committed
stubbing and experimentation
1 parent c072a72 commit 46782a9

File tree

4 files changed

+181
-7
lines changed

4 files changed

+181
-7
lines changed

src/jit/src/ir.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::rc::Rc;
2+
3+
pub enum IrSize {
4+
U8,
5+
S8,
6+
U16,
7+
S16,
8+
U32,
9+
S32
10+
11+
}
12+
13+
pub enum IrInstruction {
14+
Nop,
15+
SetConstant,
16+
SetFloatConstant,
17+
Or(Rc<IrInstruction>, Rc<IrInstruction>),
18+
Xor(Rc<IrInstruction>, Rc<IrInstruction>),
19+
And(Rc<IrInstruction>, Rc<IrInstruction>),
20+
Sub,
21+
Not,
22+
Add(Rc<IrInstruction>, Rc<IrInstruction>),
23+
Shift,
24+
Store,
25+
Load,
26+
GetPtr(u64, IrSize),
27+
SetPtr(u64, IrSize),
28+
MaskAndCast,
29+
CheckCondition,
30+
31+
// rework these
32+
SetCondBlockExitPc,
33+
SetBlockExitPc,
34+
CondBlockExit,
35+
36+
TlbLookup,
37+
LoadGuestReg,
38+
FlushGuestReg,
39+
Multiply,
40+
Divide,
41+
Eret,
42+
Call,
43+
MovRegType,
44+
FloatConvert,
45+
FloatMultiply,
46+
FloatDivide,
47+
FloatAdd,
48+
FloatSub,
49+
FloatSqrt,
50+
FloatAbs,
51+
FloatNeg,
52+
FloatCheckCondition,
53+
InterpreterFallback
54+
}

src/jit/src/ir_to_x64.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use crate::ir::IrInstruction;
2+
use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi};
3+
4+
pub fn compile(code : &[IrInstruction]) {
5+
let mut ops = dynasmrt::x64::Assembler::new().unwrap();
6+
for instr in code {
7+
match instr {
8+
IrInstruction::Nop => todo!("IR Nop"),
9+
IrInstruction::SetConstant => todo!("IR SetConstant"),
10+
IrInstruction::SetFloatConstant => todo!("IR SetFloatConstant"),
11+
IrInstruction::Or(_, _) => todo!("IR Or"),
12+
IrInstruction::Xor(_, _) => todo!("IR Xor"),
13+
IrInstruction::And(_, _) => todo!("IR And"),
14+
IrInstruction::Sub => todo!("IR Sub"),
15+
IrInstruction::Not => todo!("IR Not"),
16+
IrInstruction::Add(_, _) => todo!("IR Add"),
17+
IrInstruction::Shift => todo!("IR Shift"),
18+
IrInstruction::Store => todo!("IR Store"),
19+
IrInstruction::Load => todo!("IR Load"),
20+
IrInstruction::GetPtr(address, size) => {
21+
dynasm!(ops
22+
; .arch x64
23+
; mov rax, rcx
24+
// ; push [rsp + rsp]
25+
)
26+
},
27+
IrInstruction::SetPtr(_, _) => todo!("IR SetPtr"),
28+
IrInstruction::MaskAndCast => todo!("IR MaskAndCast"),
29+
IrInstruction::CheckCondition => todo!("IR CheckCondition"),
30+
IrInstruction::SetCondBlockExitPc => todo!("IR SetCondBlockExitPc"),
31+
IrInstruction::SetBlockExitPc => todo!("IR SetBlockExitPc"),
32+
IrInstruction::CondBlockExit => todo!("IR CondBlockExit"),
33+
IrInstruction::TlbLookup => todo!("IR TlbLookup"),
34+
IrInstruction::LoadGuestReg => todo!("IR LoadGuestReg"),
35+
IrInstruction::FlushGuestReg => todo!("IR FlushGuestReg"),
36+
IrInstruction::Multiply => todo!("IR Multiply"),
37+
IrInstruction::Divide => todo!("IR Divide"),
38+
IrInstruction::Eret => todo!("IR Eret"),
39+
IrInstruction::Call => todo!("IR Call"),
40+
IrInstruction::MovRegType => todo!("IR MovRegType"),
41+
IrInstruction::FloatConvert => todo!("IR FloatConvert"),
42+
IrInstruction::FloatMultiply => todo!("IR FloatMultiply"),
43+
IrInstruction::FloatDivide => todo!("IR FloatDivide"),
44+
IrInstruction::FloatAdd => todo!("IR FloatAdd"),
45+
IrInstruction::FloatSub => todo!("IR FloatSub"),
46+
IrInstruction::FloatSqrt => todo!("IR FloatSqrt"),
47+
IrInstruction::FloatAbs => todo!("IR FloatAbs"),
48+
IrInstruction::FloatNeg => todo!("IR FloatNeg"),
49+
IrInstruction::FloatCheckCondition => todo!("IR FloatCheckCondition"),
50+
IrInstruction::InterpreterFallback => todo!("IR InterpreterFallback"),
51+
}
52+
}
53+
54+
}

src/jit/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
mod mips_parser;
2+
mod ir;
3+
mod ir_to_x64;
4+
25
#[no_mangle]
36
pub unsafe extern fn rs_jit_compile_new_block(instructions: *mut u32, num_instructions: usize, virtual_address: u64, physical_address: u32) {
47
let safe_code = std::slice::from_raw_parts(instructions, num_instructions);

src/jit/src/mips_parser.rs

+70-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,65 @@
1+
use itertools::izip;
2+
use proc_bitfield::ConvRaw;
3+
4+
#[derive(ConvRaw, Debug)]
5+
enum MipsOpcode {
6+
CP0 = 0b010000,
7+
CP1 = 0b010001,
8+
CP2 = 0b010010,
9+
CP3 = 0b010011,
10+
LD = 0b110111,
11+
LUI = 0b001111,
12+
ADDI = 0b001000,
13+
ADDIU = 0b001001,
14+
DADDI = 0b011000,
15+
ANDI = 0b001100,
16+
LBU = 0b100100,
17+
LHU = 0b100101,
18+
LH = 0b100001,
19+
LW = 0b100011,
20+
LWU = 0b100111,
21+
BEQ = 0b000100,
22+
BEQL = 0b010100,
23+
BGTZ = 0b000111,
24+
BGTZL = 0b010111,
25+
BLEZ = 0b000110,
26+
BLEZL = 0b010110,
27+
BNE = 0b000101,
28+
BNEL = 0b010101,
29+
CACHE = 0b101111,
30+
REGIMM = 0b000001,
31+
SPCL = 0b000000,
32+
SB = 0b101000,
33+
SH = 0b101001,
34+
SD = 0b111111,
35+
SW = 0b101011,
36+
ORI = 0b001101,
37+
J = 0b000010,
38+
JAL = 0b000011,
39+
SLTI = 0b001010,
40+
SLTIU = 0b001011,
41+
XORI = 0b001110,
42+
DADDIU = 0b011001,
43+
LB = 0b100000,
44+
LDC1 = 0b110101,
45+
SDC1 = 0b111101,
46+
LWC1 = 0b110001,
47+
SWC1 = 0b111001,
48+
LWL = 0b100010,
49+
LWR = 0b100110,
50+
SWL = 0b101010,
51+
SWR = 0b101110,
52+
LDL = 0b011010,
53+
LDR = 0b011011,
54+
SDL = 0b101100,
55+
SDR = 0b101101,
56+
LL = 0b110000,
57+
LLD = 0b110100,
58+
SC = 0b111000,
59+
SCD = 0b111100,
60+
RDHWR = 0b011111
61+
}
62+
163
proc_bitfield::bitfield! {
264
#[derive(Clone, Copy, PartialEq, Eq)]
365
pub struct MipsInstruction(pub u32): Debug, FromStorage, IntoStorage, DerefStorage {
@@ -8,21 +70,22 @@ proc_bitfield::bitfield! {
870

971
pub rt: u8 @ 16 ..=20,
1072
pub rs: u8 @ 21 ..=25,
11-
pub op: u8 @ 26 ..=31,
73+
74+
pub op_bits: u8 @ 26 ..=31,
75+
pub op: u8 [unwrap MipsOpcode] @ 26 ..= 31
1276
}
1377
}
1478

1579
pub fn parse(code: &[u32], virtual_address: u64, physical_address: u32) {
1680
let instructions = code.iter().map(|word| MipsInstruction(*word));
81+
let zipped = izip!(instructions, (virtual_address..).step_by(4), (physical_address..).step_by(4));
1782

1883
let code_len = code.len();
1984
println!("Compiling {code_len} instructions at virtual address 0x{virtual_address:016X} and physical address 0x{physical_address:08X}");
2085

21-
let mut addr = virtual_address;
22-
for instr in instructions {
23-
let x = instr.raw();
24-
let opcode = instr.op();
25-
println!("{addr:016X}\t{x:08X} (opcode {opcode:X})");
26-
addr += 4;
86+
for (instruction, vaddr, paddr) in zipped {
87+
let iw = instruction.raw();
88+
let op_enum = instruction.op();
89+
println!("{vaddr:016X}\t{paddr:08X}\t{iw:08X} (opcode {op_enum:?})");
2790
}
2891
}

0 commit comments

Comments
 (0)