Skip to content

Commit 7b32b75

Browse files
committed
Fixes to atomci
1 parent 5ca5896 commit 7b32b75

File tree

8 files changed

+58
-21
lines changed

8 files changed

+58
-21
lines changed

bin/c_success_coretests.txt

+4
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,15 @@ asserting::capture_with_non_debuggable_elem_has_correct_params
7575
async_iter::into_async_iter
7676
atomic::atomic_alignment
7777
atomic::atomic_compare_exchange
78+
atomic::bool_
79+
atomic::bool_nand
7880
atomic::int_max
7981
atomic::int_min
8082
atomic::int_nand
8183
atomic::int_or
8284
atomic::int_xor
85+
atomic::ptr_add_data
86+
atomic::ptr_add_null
8387
atomic::ptr_bitops
8488
atomic::ptr_bitops_tagging
8589
atomic::static_init

cilly/src/v2/builtins/atomics.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
asm::MissingMethodPatcher, cilnode::MethodKind, cilroot::BranchCond, BasicBlock, BinOp,
2+
asm::MissingMethodPatcher, cilnode::{ExtendKind, MethodKind, PtrCastRes}, cilroot::BranchCond, BasicBlock, BinOp,
33
CILNode, CILRoot, ClassRef, Const, Int, MethodImpl, MethodRef, Type,
44
};
55

@@ -18,7 +18,7 @@ pub fn emulate_uint8_cmp_xchng(asm: &mut Assembly, patcher: &mut MissingMethodPa
1818
// 1st, mask the previous value
1919
let prev_mask = asm.alloc_node(Const::I32(0xFFFF_FF00_u32 as i32));
2020
let prev = asm.alloc_node(CILNode::BinOp(prev, prev_mask, BinOp::And));
21-
21+
let arg = asm.alloc_node(CILNode::IntCast { input:arg, target: Int::I32, extend:ExtendKind::ZeroExtend });
2222
asm.alloc_node(CILNode::BinOp(prev, arg, BinOp::Or))
2323
}),
2424
Int::I32,
@@ -31,7 +31,7 @@ pub fn emulate_uint8_cmp_xchng(asm: &mut Assembly, patcher: &mut MissingMethodPa
3131
// 1st, mask the previous value
3232
let prev_mask = asm.alloc_node(Const::I32(0xFFFF_0000_u32 as i32));
3333
let prev = asm.alloc_node(CILNode::BinOp(prev, prev_mask, BinOp::And));
34-
34+
let arg = asm.alloc_node(CILNode::IntCast { input:arg, target: Int::I32, extend:ExtendKind::ZeroExtend });
3535
asm.alloc_node(CILNode::BinOp(prev, arg, BinOp::Or))
3636
}),
3737
Int::I32,
@@ -74,10 +74,10 @@ pub fn compare_exchange(
7474
match int.size().unwrap_or(8) {
7575
// u16 is buggy :(. TODO: fix it.
7676
1 | 2 => {
77-
let compare_exchange = asm.alloc_string("atomic_cmpxchng8_i32");
77+
let compare_exchange = asm.alloc_string(format!("atomic_cmpxchng{}_i32",int.size().unwrap_or(8) * 8));
7878

7979
let i32 = Type::Int(int);
80-
let i32_ref = asm.nref(i32);
80+
let i32_ref = asm.nref(Type::Int(Int::I32));
8181
let cmpxchng_sig = asm.sig([i32_ref, i32, i32], i32);
8282
let main_mod = asm.main_module();
8383
let mref = asm.alloc_methodref(MethodRef::new(
@@ -89,12 +89,12 @@ pub fn compare_exchange(
8989
));
9090
let cast_value = asm.alloc_node(CILNode::IntCast {
9191
input: value,
92-
target: Int::I32,
92+
target: int,
9393
extend: crate::cilnode::ExtendKind::ZeroExtend,
9494
});
9595
let cast_comparand = asm.alloc_node(CILNode::IntCast {
9696
input: comaprand,
97-
target: Int::I32,
97+
target: int,
9898
extend: crate::cilnode::ExtendKind::ZeroExtend,
9999
});
100100
let addr = asm.alloc_node(CILNode::RefToPtr(addr));

cilly/src/v2/c_exporter/c_header.h

+3
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,9 @@ static inline uint32_t System_Threading_Interlocked_CompareExchangeru32u32u32u32
613613
return comparand;
614614
}
615615
}
616+
static inline int32_t System_Threading_Interlocked_CompareExchangeri32i32i32i32(int32_t* addr, int32_t value, int32_t comparand){
617+
return System_Threading_Interlocked_CompareExchangeru32u32u32u32((uint32_t *) addr, value, comparand);
618+
}
616619
static inline uint64_t System_Threading_Interlocked_CompareExchangeru64u64u64u64(uint64_t *addr, uint64_t value, uint64_t comparand)
617620
{
618621
uint64_t res = 0;

cilly/src/v2/tpe/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,17 @@ impl Type {
7474
}
7575
#[must_use]
7676
pub fn deref<'a, 'b: 'a>(&'a self, asm: &'b Assembly) -> &'a Self {
77-
match self {
78-
Type::Ptr(inner) | Type::Ref(inner) => &asm[*inner],
79-
_ => panic!(),
80-
}
77+
self.try_deref(asm).unwrap()
78+
}
79+
#[must_use]
80+
pub fn try_deref<'a, 'b: 'a>(&'a self, asm: &'b Assembly) -> Option<&'a Self >{
81+
match self {
82+
Type::Ptr(inner) | Type::Ref(inner) => Some(&asm[*inner]),
83+
_ => None,
8184
}
85+
}
86+
87+
8288
/// Returns a mangled ASCI representation of this type.
8389
/// ```
8490
/// # use cilly::*;

cilly/src/v2/typecheck.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ pub enum TypeCheckError {
5555
/// A call instruction was passed a wrong argument type.
5656
CallArgTypeWrong {
5757
/// The recived type
58-
got: Type,
58+
got: String,
5959
/// The expected type
60-
expected: Type,
60+
expected: String,
6161
/// The inddex of this argument
6262
idx: usize,
6363
/// The called method
@@ -675,10 +675,10 @@ impl CILNode {
675675
for (idx, (arg, input_type)) in args.iter().zip(inputs.iter()).enumerate() {
676676
let arg = asm.get_node(*arg).clone();
677677
let arg_type = arg.typecheck(sig, locals, asm)?;
678-
if !arg_type.is_assignable_to(*input_type, asm) {
678+
if !arg_type.is_assignable_to(*input_type, asm)&& !arg_type.try_deref(asm).is_some_and(|t|Some(t) == input_type.try_deref(asm)){
679679
return Err(TypeCheckError::CallArgTypeWrong {
680-
got: arg_type,
681-
expected: *input_type,
680+
got: arg_type.mangle(asm),
681+
expected: input_type.mangle(asm),
682682
idx,
683683
mname: asm[mref.name()].into(),
684684
});

src/terminator/intrinsics/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ pub fn handle_intrinsic<'tcx>(
320320
);
321321
vec![place_set(
322322
destination,
323-
atomic_add(dst, add_ammount.clone(), Type::Int(Int::USize), ctx)
323+
atomic_add(dst, add_ammount.clone(),src_type, ctx)
324324
.cast_ptr(src_type),
325325
ctx,
326326
)]

src/terminator/intrinsics/utilis.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ pub fn atomic_add(addr: CILNode, addend: CILNode, tpe: Type, asm: &mut Assembly)
3232
call!(
3333
asm.alloc_methodref(mref),
3434
[
35-
addr.cast_ptr(asm.nptr(Type::Int(Int::USize))),
35+
addr.cast_ptr(usize_ref),
3636
addend.cast_ptr(Type::Int(Int::USize))
3737
]
38-
)
38+
).cast_ptr(tpe)
3939
}
4040

4141
_ => todo!(),
@@ -95,7 +95,7 @@ pub fn atomic_or(addr: CILNode, addend: CILNode, tpe: Type, asm: &mut Assembly)
9595
addend.cast_ptr(Type::Int(Int::USize))
9696
]
9797
);
98-
cilnode.cast_ptr(Type::Ptr(inner))
98+
cilnode.cast_ptr(Type::Ptr(inner)).cast_ptr(tpe)
9999
}
100100
_ => todo!("Can't atomic or {tpe:?}"),
101101
}

test/intrinsics/atomics.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fn ptr_bitops_tagging() {
111111
ptr.map_addr(|a| a | 0b1001)
112112
);
113113
test_eq!(atom.load(SeqCst), ptr);
114-
//add_data();
114+
ptr_add_data();
115115
}
116116
fn add_data() {
117117
let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
@@ -127,3 +127,27 @@ fn add_data() {
127127
test_eq!(atom.fetch_byte_sub(1, SeqCst).addr(), 1);
128128
test_eq!(atom.load(SeqCst).addr(), 0);
129129
}
130+
#[no_mangle]
131+
fn ptr_add_data() {
132+
let num = 0i64;
133+
let n = &num as *const i64 as *mut _;
134+
let atom = AtomicPtr::<i64>::new(n);
135+
test_eq!(atom.fetch_ptr_add(1, SeqCst), n);
136+
test_eq!(atom.load(SeqCst), n.wrapping_add(1));
137+
138+
test_eq!(atom.fetch_ptr_sub(1, SeqCst), n.wrapping_add(1));
139+
test_eq!(atom.load(SeqCst), n);
140+
let bytes_from_n = |b| n.wrapping_byte_add(b);
141+
142+
test_eq!(atom.fetch_byte_add(1, SeqCst), n);
143+
test_eq!(atom.load(SeqCst), bytes_from_n(1));
144+
145+
test_eq!(atom.fetch_byte_add(5, SeqCst), bytes_from_n(1));
146+
test_eq!(atom.load(SeqCst), bytes_from_n(6));
147+
148+
test_eq!(atom.fetch_byte_sub(1, SeqCst), bytes_from_n(6));
149+
test_eq!(atom.load(SeqCst), bytes_from_n(5));
150+
151+
test_eq!(atom.fetch_byte_sub(5, SeqCst), bytes_from_n(5));
152+
test_eq!(atom.load(SeqCst), n);
153+
}

0 commit comments

Comments
 (0)