Skip to content

Commit

Permalink
Some fixes to the C mode.
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Nov 2, 2024
1 parent 55003dd commit 77ef069
Show file tree
Hide file tree
Showing 19 changed files with 300 additions and 168 deletions.
10 changes: 7 additions & 3 deletions cilly/src/bin/linker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ fn main() {
}),
);
// Override allocator
{
if !*C_MODE {
// Get the marshal class
let marshal = ClassRef::marshal(&mut final_assembly);
// Overrides calls to malloc
Expand Down Expand Up @@ -361,14 +361,18 @@ fn main() {
cilly::v2::builtins::insert_swap_at_generic(&mut final_assembly, &mut overrides);
cilly::v2::builtins::insert_bounds_check(&mut final_assembly, &mut overrides);
cilly::v2::builtins::casts::insert_casts(&mut final_assembly, &mut overrides);
cilly::v2::builtins::insert_heap(&mut final_assembly, &mut overrides);
cilly::v2::builtins::insert_heap(&mut final_assembly, &mut overrides, *C_MODE);
cilly::v2::builtins::int128::generate_int128_ops(&mut final_assembly, &mut overrides, *C_MODE);
cilly::v2::builtins::int128::i128_mul_ovf_check(&mut final_assembly, &mut overrides);
cilly::v2::builtins::f16::generate_f16_ops(&mut final_assembly, &mut overrides, *C_MODE);
cilly::v2::builtins::atomics::generate_all_atomics(&mut final_assembly, &mut overrides);
if *C_MODE {
cilly::v2::builtins::insert_exeception_stub(&mut final_assembly, &mut overrides);
externs.insert("__dso_handle", LIBC.clone());
externs.insert("_mm_malloc", LIBC.clone());
externs.insert("_mm_free", LIBC.clone());
externs.insert("abort", LIBC.clone());
} else {
cilly::v2::builtins::atomics::generate_all_atomics(&mut final_assembly, &mut overrides);
cilly::v2::builtins::instert_threading(&mut final_assembly, &mut overrides);
cilly::v2::builtins::math::math(&mut final_assembly, &mut overrides);
cilly::v2::builtins::simd::simd(&mut final_assembly, &mut overrides);
Expand Down
2 changes: 1 addition & 1 deletion cilly/src/bin/linker/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn call_alias(
asm.alloc_node(CILNode::LdInd {
addr: ptr_address,
tpe,
volitale: false,
volatile: false,
})
}
(
Expand Down
4 changes: 2 additions & 2 deletions cilly/src/v2/asm_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl Assembly {
CILNode::LdInd {
addr,
tpe,
volitale,
volatile: volitale,
} => {
let addr = self.translate_node(source, source.get_node(*addr).clone());
let addr = self.alloc_node(addr);
Expand All @@ -208,7 +208,7 @@ impl Assembly {
CILNode::LdInd {
addr,
tpe,
volitale: *volitale,
volatile: *volitale,
}
}
CILNode::SizeOf(tpe) => {
Expand Down
23 changes: 17 additions & 6 deletions cilly/src/v2/builtins/atomics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn emulate_uint8_cmp_xchng(asm: &mut Assembly, patcher: &mut MissingMethodPa
let arg0_val = asm.alloc_node(CILNode::LdInd {
addr: ldarg_0,
tpe: uint8_idx,
volitale: true,
volatile: true,
});
let set_tmp = asm.alloc_root(CILRoot::StLoc(0, arg0_val));
// Copy arg1 to addr0
Expand Down Expand Up @@ -91,22 +91,27 @@ pub fn generate_atomic(
mref,
Box::new([ldarg_0, op, ldloc_0]),
))));

let zero = asm.alloc_node(int.zero());
let entry_block = vec![
asm.alloc_root(CILRoot::StLoc(1, zero)),
asm.alloc_root(CILRoot::Branch(Box::new((1, 0, None)))),
];
let loop_block = vec![
asm.alloc_root(CILRoot::StLoc(0, ldloc_1)),
asm.alloc_root(CILRoot::StLoc(1, call)),
asm.alloc_root(CILRoot::Branch(Box::new((
0,
0,
1,
Some(BranchCond::Ne(ldloc_0, ldloc_1)),
)))),
asm.alloc_root(CILRoot::Branch(Box::new((1, 0, None)))),
asm.alloc_root(CILRoot::Branch(Box::new((2, 0, None)))),
];
let exit_block = vec![asm.alloc_root(CILRoot::Ret(ldloc_0))];
MethodImpl::MethodBody {
blocks: vec![
BasicBlock::new(loop_block, 0, None),
BasicBlock::new(exit_block, 1, None),
BasicBlock::new(entry_block, 0, None),
BasicBlock::new(loop_block, 1, None),
BasicBlock::new(exit_block, 2, None),
],
locals: vec![(None, asm.alloc_type(tpe)), (None, asm.alloc_type(tpe))],
}
Expand All @@ -133,6 +138,12 @@ pub fn generate_atomic_for_ints(
}
/// Adds all the builitn atomic functions to the patcher, allowing for their use.
pub fn generate_all_atomics(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
generate_atomic_for_ints(asm, patcher, "add", |asm, lhs, rhs, _| {
asm.alloc_node(CILNode::BinOp(lhs, rhs, BinOp::Add))
});
generate_atomic_for_ints(asm, patcher, "sub", |asm, lhs, rhs, _| {
asm.alloc_node(CILNode::BinOp(lhs, rhs, BinOp::Sub))
});
// XOR
generate_atomic_for_ints(asm, patcher, "xor", |asm, lhs, rhs, _| {
asm.alloc_node(CILNode::BinOp(lhs, rhs, BinOp::XOr))
Expand Down
233 changes: 164 additions & 69 deletions cilly/src/v2/builtins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::num::NonZeroU32;

use super::{
asm::MissingMethodPatcher, cilnode::MethodKind, cilroot::BranchCond, Access, Assembly,
BasicBlock, CILNode, CILRoot, ClassDef, ClassRef, Const, FieldDesc, Int, MethodDef, MethodImpl,
MethodRef, Type,
asm::MissingMethodPatcher,
cilnode::{MethodKind, PtrCastRes},
cilroot::BranchCond,
Access, Assembly, BasicBlock, CILNode, CILRoot, ClassDef, ClassRef, Const, FieldDesc, Int,
MethodDef, MethodImpl, MethodRef, Type,
};

pub mod atomics;
Expand Down Expand Up @@ -160,71 +162,165 @@ fn insert_rust_alloc_zeroed(asm: &mut Assembly, patcher: &mut MissingMethodPatch
};
patcher.insert(name, Box::new(generator));
}
fn insert_rust_realloc(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
fn insert_rust_realloc(asm: &mut Assembly, patcher: &mut MissingMethodPatcher, use_libc: bool) {
let name = asm.alloc_string("__rust_realloc");
let generator = move |_, asm: &mut Assembly| {
let ptr = asm.alloc_node(CILNode::LdArg(0));
let align = asm.alloc_node(CILNode::LdArg(2));
let new_size = asm.alloc_node(CILNode::LdArg(3));
let align = asm.alloc_node(CILNode::IntCast {
input: align,
target: Int::USize,
extend: super::cilnode::ExtendKind::ZeroExtend,
});
let new_size = asm.alloc_node(CILNode::IntCast {
input: new_size,
target: Int::USize,
extend: super::cilnode::ExtendKind::ZeroExtend,
});
let void_ptr = asm.nptr(Type::Void);
let sig = asm.sig(
[void_ptr, Type::Int(Int::USize), Type::Int(Int::USize)],
void_ptr,
);
let aligned_realloc = asm.alloc_string("AlignedRealloc");
let native_mem = ClassRef::native_mem(asm);
let call_method = asm.alloc_methodref(MethodRef::new(
native_mem,
aligned_realloc,
sig,
MethodKind::Static,
[].into(),
));
let alloc = asm.alloc_node(CILNode::Call(Box::new((
call_method,
Box::new([ptr, new_size, align]),
))));
let ret = asm.alloc_root(CILRoot::Ret(alloc));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
if use_libc {
let generator = move |_, asm: &mut Assembly| {
let ptr = asm.alloc_node(CILNode::LdArg(0));
let void_idx = asm.alloc_type(Type::Void);
let ptr = asm.alloc_node(CILNode::PtrCast(
ptr,
Box::new(super::cilnode::PtrCastRes::Ptr(void_idx)),
));
let align = asm.alloc_node(CILNode::LdArg(2));
let new_size = asm.alloc_node(CILNode::LdArg(3));
let align = asm.alloc_node(CILNode::IntCast {
input: align,
target: Int::USize,
extend: super::cilnode::ExtendKind::ZeroExtend,
});
let new_size = asm.alloc_node(CILNode::IntCast {
input: new_size,
target: Int::USize,
extend: super::cilnode::ExtendKind::ZeroExtend,
});
let void_ptr = asm.nptr(Type::Void);
let mm_malloc_sig = asm.sig([Type::Int(Int::USize), Type::Int(Int::USize)], void_ptr);
// 1. call _mm_malloc
let aligned_realloc = asm.alloc_string("_mm_malloc");
let main_module = asm.main_module();
let _mm_malloc = asm.alloc_methodref(MethodRef::new(
*main_module,
aligned_realloc,
mm_malloc_sig,
MethodKind::Static,
[].into(),
));
let _mm_malloc = asm.alloc_node(CILNode::Call(Box::new((
_mm_malloc,
Box::new([new_size, align]),
))));
let call_mm_malloc = asm.alloc_root(CILRoot::StLoc(0, _mm_malloc));
// 2. memcpy the buffer.
let buff = asm.alloc_node(CILNode::LdLoc(0));
let copy = asm.alloc_root(CILRoot::CpBlk(Box::new((buff, ptr, new_size))));
// 3. free the old buffer
let aligned_free = asm.alloc_string("_mm_free");
let mm_free_sig = asm.sig([void_ptr], Type::Void);
let aligned_free = asm.alloc_methodref(MethodRef::new(
*main_module,
aligned_free,
mm_free_sig,
MethodKind::Static,
[].into(),
));
let call_aligned_free =
asm.alloc_root(CILRoot::Call(Box::new((aligned_free, [ptr].into()))));
let ret = asm.alloc_root(CILRoot::Ret(buff));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(
vec![call_mm_malloc, copy, call_aligned_free, ret],
0,
None,
)],
locals: vec![(None, asm.alloc_type(void_ptr))],
}
};
patcher.insert(name, Box::new(generator));
} else {
let generator = move |_, asm: &mut Assembly| {
let ptr = asm.alloc_node(CILNode::LdArg(0));
let align = asm.alloc_node(CILNode::LdArg(2));
let new_size = asm.alloc_node(CILNode::LdArg(3));
let align = asm.alloc_node(CILNode::IntCast {
input: align,
target: Int::USize,
extend: super::cilnode::ExtendKind::ZeroExtend,
});
let new_size = asm.alloc_node(CILNode::IntCast {
input: new_size,
target: Int::USize,
extend: super::cilnode::ExtendKind::ZeroExtend,
});
let void_ptr = asm.nptr(Type::Void);
let sig = asm.sig(
[void_ptr, Type::Int(Int::USize), Type::Int(Int::USize)],
void_ptr,
);
let aligned_realloc = asm.alloc_string("AlignedRealloc");
let native_mem = ClassRef::native_mem(asm);
let call_method = asm.alloc_methodref(MethodRef::new(
native_mem,
aligned_realloc,
sig,
MethodKind::Static,
[].into(),
));
let alloc = asm.alloc_node(CILNode::Call(Box::new((
call_method,
Box::new([ptr, new_size, align]),
))));
let ret = asm.alloc_root(CILRoot::Ret(alloc));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
}
}
fn insert_rust_dealloc(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
fn insert_rust_dealloc(asm: &mut Assembly, patcher: &mut MissingMethodPatcher, use_libc: bool) {
let name = asm.alloc_string("__rust_dealloc");
let generator = move |_, asm: &mut Assembly| {
let ldarg_0 = asm.alloc_node(CILNode::LdArg(0));
let void_ptr = asm.nptr(Type::Void);
let sig = asm.sig([void_ptr], Type::Void);
let aligned_realloc = asm.alloc_string("AlignedFree");
let native_mem = ClassRef::native_mem(asm);
let call_method = asm.alloc_methodref(MethodRef::new(
native_mem,
aligned_realloc,
sig,
MethodKind::Static,
[].into(),
));
let alloc = asm.alloc_node(CILNode::Call(Box::new((call_method, Box::new([ldarg_0])))));
let ret = asm.alloc_root(CILRoot::Ret(alloc));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
if use_libc {
let generator = move |_, asm: &mut Assembly| {
let ldarg_0 = asm.alloc_node(CILNode::LdArg(0));
let void_idx = asm.alloc_type(Type::Void);
let ldarg_0 = asm.alloc_node(CILNode::PtrCast(
ldarg_0,
Box::new(PtrCastRes::Ptr(void_idx)),
));
let void_ptr = asm.nptr(Type::Void);
let sig = asm.sig([void_ptr], Type::Void);
let mm_free = asm.alloc_string("_mm_free");
let main_module = asm.main_module();
let call_method = asm.alloc_methodref(MethodRef::new(
*main_module,
mm_free,
sig,
MethodKind::Static,
[].into(),
));
let alloc = asm.alloc_node(CILNode::Call(Box::new((call_method, Box::new([ldarg_0])))));
let ret = asm.alloc_root(CILRoot::Ret(alloc));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
} else {
let generator = move |_, asm: &mut Assembly| {
let ldarg_0 = asm.alloc_node(CILNode::LdArg(0));
let void_ptr = asm.nptr(Type::Void);
let sig = asm.sig([void_ptr], Type::Void);
let aligned_realloc = asm.alloc_string("AlignedFree");
let native_mem = ClassRef::native_mem(asm);
let call_method = asm.alloc_methodref(MethodRef::new(
native_mem,
aligned_realloc,
sig,
MethodKind::Static,
[].into(),
));
let alloc = asm.alloc_node(CILNode::Call(Box::new((call_method, Box::new([ldarg_0])))));
let ret = asm.alloc_root(CILRoot::Ret(alloc));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
}
}
pub fn insert_exeception_stub(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let rust_exception = asm.alloc_string("RustException");
Expand Down Expand Up @@ -288,12 +384,11 @@ pub fn insert_exception(asm: &mut Assembly, patcher: &mut MissingMethodPatcher)
));
insert_catch_unwind(asm, patcher);
}
pub fn insert_heap(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
pub fn insert_heap(asm: &mut Assembly, patcher: &mut MissingMethodPatcher, use_libc: bool) {
insert_rust_alloc(asm, patcher);
insert_rust_alloc_zeroed(asm, patcher);
insert_rust_realloc(asm, patcher);
insert_rust_dealloc(asm, patcher);

insert_rust_realloc(asm, patcher, use_libc);
insert_rust_dealloc(asm, patcher, use_libc);
insert_pause(asm, patcher);
}

Expand Down
2 changes: 1 addition & 1 deletion cilly/src/v2/builtins/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ fn insert_pthread_create(asm: &mut Assembly, patcher: &mut MissingMethodPatcher)
let transmute_arg_2 = asm.alloc_node(CILNode::LdInd {
addr: arg2_addr,
tpe: start_fn_ptr_type,
volitale: false,
volatile: false,
});
let transmute_arg_2 = asm.alloc_root(CILRoot::StLoc(2, transmute_arg_2));
// Arg2 needs to be transmuted, and the local 2 holds the transmuted value of arg2.
Expand Down
Loading

0 comments on commit 77ef069

Please sign in to comment.