Skip to content

Commit 445ad57

Browse files
committed
Fixes for niche encoding tags of 128 bit sides
1 parent 6c9576c commit 445ad57

File tree

5 files changed

+412
-73
lines changed

5 files changed

+412
-73
lines changed

cilly/src/cil_node.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,62 @@ pub enum CILNode {
235235
}
236236

237237
impl CILNode {
238+
pub fn const_u128(value: u128) -> CILNode {
239+
fn u128_low_u64(value: u128) -> u64 {
240+
u64::try_from(value & u128::from(u64::MAX)).expect("trucating cast error")
241+
}
242+
let low = u128_low_u64(value);
243+
let high = (value >> 64) as u64;
244+
let ctor_sig = FnSig::new(
245+
&[
246+
Type::ManagedReference(Type::U128.into()),
247+
Type::U64,
248+
Type::U64,
249+
],
250+
Type::Void,
251+
);
252+
CILNode::NewObj(Box::new(CallOpArgs {
253+
site: CallSite::boxed(
254+
Some(DotnetTypeRef::uint_128()),
255+
".ctor".into(),
256+
ctor_sig,
257+
false,
258+
),
259+
args: [
260+
crate::conv_u64!(crate::ldc_u64!(high)),
261+
crate::conv_u64!(crate::ldc_u64!(low)),
262+
]
263+
.into(),
264+
}))
265+
}
266+
pub fn const_i128(value: u128) -> CILNode {
267+
fn u128_low_u64(value: u128) -> u64 {
268+
u64::try_from(value & u128::from(u64::MAX)).expect("trucating cast error")
269+
}
270+
let low = u128_low_u64(value);
271+
let high = (value >> 64) as u64;
272+
let ctor_sig = FnSig::new(
273+
&[
274+
Type::ManagedReference(Type::I128.into()),
275+
Type::U64,
276+
Type::U64,
277+
],
278+
Type::Void,
279+
);
280+
CILNode::NewObj(Box::new(CallOpArgs {
281+
site: CallSite::boxed(
282+
Some(DotnetTypeRef::int_128()),
283+
".ctor".into(),
284+
ctor_sig,
285+
false,
286+
),
287+
args: [
288+
crate::conv_u64!(crate::ldc_u64!(high)),
289+
crate::conv_u64!(crate::ldc_u64!(low)),
290+
]
291+
.into(),
292+
}))
293+
}
238294
/// Allocates a GC handle to the object, and converts that handle to a nint sized handleID.
239295
pub fn managed_ref_to_handle(self) -> Self {
240296
let gc_handle = call!(
@@ -1639,7 +1695,13 @@ impl std::ops::BitOr<Self> for CILNode {
16391695
or!(self, rhs)
16401696
}
16411697
}
1698+
impl std::ops::BitAnd<Self> for CILNode {
1699+
type Output = Self;
16421700

1701+
fn bitand(self, rhs: Self) -> Self::Output {
1702+
and!(self, rhs)
1703+
}
1704+
}
16431705
impl std::ops::Neg for CILNode {
16441706
fn neg(self) -> Self::Output {
16451707
Self::Neg(self.into())

src/builtin/mod.rs

Lines changed: 128 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use cilly::{
1515
method::{Method, MethodType},
1616
ptr,
1717
r#type::Type,
18-
size_of, source_info,
18+
shl, shr, size_of, source_info,
1919
static_field_desc::StaticFieldDescriptor,
2020
type_def::TypeDef,
2121
utilis::escape_class_name,
@@ -206,6 +206,8 @@ pub fn insert_ffi_functions(asm: &mut Assembly, tcx: TyCtxt) {
206206
bounds_check(asm);
207207
atomic::atomics(asm);
208208
bitreverse_u128(asm);
209+
bitreverse_u64(asm);
210+
bitreverse_u32(asm);
209211
let c_void = crate::r#type::c_void(tcx);
210212

211213
asm.add_typedef(TypeDef::new(
@@ -1374,27 +1376,7 @@ fn shl_u128(value: CILNode, shift: CILNode) -> CILNode {
13741376
[value, shift]
13751377
)
13761378
}
1377-
fn const_u128(value: u128) -> CILNode {
1378-
let low = u128_low_u64(value);
1379-
let high = (value >> 64) as u64;
1380-
let ctor_sig = FnSig::new(
1381-
&[
1382-
Type::ManagedReference(Type::U128.into()),
1383-
Type::U64,
1384-
Type::U64,
1385-
],
1386-
Type::Void,
1387-
);
1388-
CILNode::NewObj(Box::new(CallOpArgs {
1389-
site: CallSite::boxed(
1390-
Some(DotnetTypeRef::uint_128()),
1391-
".ctor".into(),
1392-
ctor_sig,
1393-
false,
1394-
),
1395-
args: [conv_u64!(ldc_u64!(high)), conv_u64!(ldc_u64!(low))].into(),
1396-
}))
1397-
}
1379+
13981380
add_method_from_trees!(
13991381
bitreverse_u128,
14001382
&[Type::U128],
@@ -1406,12 +1388,12 @@ add_method_from_trees!(
14061388
tree: or_u128(
14071389
and_u128(
14081390
shr_u128(CILNode::LDArg(0), ldc_i32!(1)),
1409-
const_u128(0x5555_5555_5555_5555_5555_5555_5555_5555_u128),
1391+
CILNode::const_u128(0x5555_5555_5555_5555_5555_5555_5555_5555_u128),
14101392
),
14111393
shl_u128(
14121394
and_u128(
14131395
CILNode::LDArg(0),
1414-
const_u128(0x5555_5555_5555_5555_5555_5555_5555_5555_u128),
1396+
CILNode::const_u128(0x5555_5555_5555_5555_5555_5555_5555_5555_u128),
14151397
),
14161398
ldc_i32!(1),
14171399
),
@@ -1423,12 +1405,12 @@ add_method_from_trees!(
14231405
tree: or_u128(
14241406
and_u128(
14251407
shr_u128(CILNode::LDLoc(0), ldc_i32!(2)),
1426-
const_u128(0x3333_3333_3333_3333_3333_3333_3333_3333_u128),
1408+
CILNode::const_u128(0x3333_3333_3333_3333_3333_3333_3333_3333_u128),
14271409
),
14281410
shl_u128(
14291411
and_u128(
14301412
CILNode::LDLoc(0),
1431-
const_u128(0x3333_3333_3333_3333_3333_3333_3333_3333_u128),
1413+
CILNode::const_u128(0x3333_3333_3333_3333_3333_3333_3333_3333_u128),
14321414
),
14331415
ldc_i32!(2),
14341416
),
@@ -1440,12 +1422,12 @@ add_method_from_trees!(
14401422
tree: or_u128(
14411423
and_u128(
14421424
shr_u128(CILNode::LDLoc(0), ldc_i32!(4)),
1443-
const_u128(0x0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_u128),
1425+
CILNode::const_u128(0x0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_u128),
14441426
),
14451427
shl_u128(
14461428
and_u128(
14471429
CILNode::LDLoc(0),
1448-
const_u128(0x0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_u128),
1430+
CILNode::const_u128(0x0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_0F0F_u128),
14491431
),
14501432
ldc_i32!(4),
14511433
),
@@ -1457,12 +1439,12 @@ add_method_from_trees!(
14571439
tree: or_u128(
14581440
and_u128(
14591441
shr_u128(CILNode::LDLoc(0), ldc_i32!(8)),
1460-
const_u128(0x00FF_00FF_00FF_00FF_00FF_00FF_00FF_00FF_u128),
1442+
CILNode::const_u128(0x00FF_00FF_00FF_00FF_00FF_00FF_00FF_00FF_u128),
14611443
),
14621444
shl_u128(
14631445
and_u128(
14641446
CILNode::LDLoc(0),
1465-
const_u128(0x00FF_00FF_00FF_00FF_00FF_00FF_00FF_00FF_u128),
1447+
CILNode::const_u128(0x00FF_00FF_00FF_00FF_00FF_00FF_00FF_00FF_u128),
14661448
),
14671449
ldc_i32!(8),
14681450
),
@@ -1474,12 +1456,12 @@ add_method_from_trees!(
14741456
tree: or_u128(
14751457
and_u128(
14761458
shr_u128(CILNode::LDLoc(0), ldc_i32!(16)),
1477-
const_u128(0x0000_FFFF_0000_FFFF_0000_FFFF_0000_FFFF_u128),
1459+
CILNode::const_u128(0x0000_FFFF_0000_FFFF_0000_FFFF_0000_FFFF_u128),
14781460
),
14791461
shl_u128(
14801462
and_u128(
14811463
CILNode::LDLoc(0),
1482-
const_u128(0x0000_FFFF_0000_FFFF_0000_FFFF_0000_FFFF_u128),
1464+
CILNode::const_u128(0x0000_FFFF_0000_FFFF_0000_FFFF_0000_FFFF_u128),
14831465
),
14841466
ldc_i32!(16),
14851467
),
@@ -1491,12 +1473,12 @@ add_method_from_trees!(
14911473
tree: or_u128(
14921474
and_u128(
14931475
shr_u128(CILNode::LDLoc(0), ldc_i32!(32)),
1494-
const_u128(0x0000_0000_FFFF_FFFF_0000_0000_FFFF_FFFF_u128),
1476+
CILNode::const_u128(0x0000_0000_FFFF_FFFF_0000_0000_FFFF_FFFF_u128),
14951477
),
14961478
shl_u128(
14971479
and_u128(
14981480
CILNode::LDLoc(0),
1499-
const_u128(0x0000_0000_FFFF_FFFF_0000_0000_FFFF_FFFF_u128),
1481+
CILNode::const_u128(0x0000_0000_FFFF_FFFF_0000_0000_FFFF_FFFF_u128),
15001482
),
15011483
ldc_i32!(32),
15021484
),
@@ -1515,12 +1497,116 @@ add_method_from_trees!(
15151497
None
15161498
)],
15171499
vec![(Some("n".into()), Type::U128)],
1518-
vec![
1519-
Some("buf1".into()),
1520-
Some("buf2".into()),
1521-
Some("size".into())
1522-
]
1500+
vec![Some("input".into()),]
1501+
);
1502+
add_method_from_trees!(
1503+
bitreverse_u64,
1504+
&[Type::U64],
1505+
Type::U64,
1506+
vec![BasicBlock::new(
1507+
vec![
1508+
CILRoot::STLoc {
1509+
local: 0,
1510+
tree: shr!(CILNode::LDArg(0), ldc_i32!(1)) & ldc_u64!(0x5555_5555_5555_5555_u64)
1511+
| shl!(
1512+
(CILNode::LDArg(0) & ldc_u64!(0x5555_5555_5555_5555_u64)),
1513+
ldc_i32!(1)
1514+
)
1515+
}
1516+
.into(),
1517+
CILRoot::STLoc {
1518+
local: 0,
1519+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(2)) & ldc_u64!(0x3333_3333_3333_3333_u64)
1520+
| shl!(
1521+
(CILNode::LDLoc(0) & ldc_u64!(0x3333_3333_3333_3333_u64)),
1522+
ldc_i32!(2)
1523+
)
1524+
}
1525+
.into(),
1526+
CILRoot::STLoc {
1527+
local: 0,
1528+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(4)) & ldc_u64!(0x0F0F_0F0F_0F0F_0F0F_u64)
1529+
| shl!(
1530+
(CILNode::LDLoc(0) & ldc_u64!(0x0F0F_0F0F_0F0F_0F0F_u64)),
1531+
ldc_i32!(4)
1532+
)
1533+
}
1534+
.into(),
1535+
CILRoot::STLoc {
1536+
local: 0,
1537+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(8)) & ldc_u64!(0x00FF_00FF_00FF_00FF_u64)
1538+
| shl!(
1539+
(CILNode::LDLoc(0) & ldc_u64!(0x00FF_00FF_00FF_00FF_u64)),
1540+
ldc_i32!(8)
1541+
)
1542+
}
1543+
.into(),
1544+
CILRoot::STLoc {
1545+
local: 0,
1546+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(16)) & ldc_u64!(0x0000_FFFF_0000_FFFF_u64)
1547+
| shl!(
1548+
(CILNode::LDLoc(0) & ldc_u64!(0x0000_FFFF_0000_FFFF_u64)),
1549+
ldc_i32!(16)
1550+
)
1551+
}
1552+
.into(),
1553+
CILRoot::Ret {
1554+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(32)) & ldc_u64!(0x0000_0000_FFFF_FFFF_u64)
1555+
| shl!(
1556+
(CILNode::LDLoc(0) & ldc_u64!(0x0000_0000_FFFF_FFFF_u64)),
1557+
ldc_i32!(32)
1558+
)
1559+
}
1560+
.into()
1561+
],
1562+
0,
1563+
None
1564+
)],
1565+
vec![(Some("n".into()), Type::U64)],
1566+
vec![Some("input".into()),]
1567+
);
1568+
add_method_from_trees!(
1569+
bitreverse_u32,
1570+
&[Type::U32],
1571+
Type::U32,
1572+
vec![BasicBlock::new(
1573+
vec![
1574+
CILRoot::STLoc {
1575+
local: 0,
1576+
tree: shr!(CILNode::LDArg(0), ldc_i32!(1)) & ldc_u32!(0x5555_5555_u32)
1577+
| shl!((CILNode::LDArg(0) & ldc_u32!(0x5555_5555_u32)), ldc_i32!(1))
1578+
}
1579+
.into(),
1580+
CILRoot::STLoc {
1581+
local: 0,
1582+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(2)) & ldc_u32!(0x3333_3333_u32)
1583+
| shl!((CILNode::LDLoc(0) & ldc_u32!(0x3333_3333_u32)), ldc_i32!(2))
1584+
}
1585+
.into(),
1586+
CILRoot::STLoc {
1587+
local: 0,
1588+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(4)) & ldc_u32!(0x0F0F_0F0F_u32)
1589+
| shl!((CILNode::LDLoc(0) & ldc_u32!(0x0F0F_0F0F_u32)), ldc_i32!(4))
1590+
}
1591+
.into(),
1592+
CILRoot::STLoc {
1593+
local: 0,
1594+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(8)) & ldc_u32!(0x00FF_00FF_u32)
1595+
| shl!((CILNode::LDLoc(0) & ldc_u32!(0x00FF_00FF_u32)), ldc_i32!(8))
1596+
}
1597+
.into(),
1598+
CILRoot::Ret {
1599+
tree: shr!(CILNode::LDLoc(0), ldc_i32!(16)) & ldc_u32!(0x0000_FFFF_u32)
1600+
| shl!(
1601+
(CILNode::LDLoc(0) & ldc_u32!(0x0000_FFFF_u32)),
1602+
ldc_i32!(16)
1603+
)
1604+
}
1605+
.into()
1606+
],
1607+
0,
1608+
None
1609+
)],
1610+
vec![(Some("n".into()), Type::U32)],
1611+
vec![Some("input".into()),]
15231612
);
1524-
fn u128_low_u64(value: u128) -> u64 {
1525-
u64::try_from(value & u128::from(u64::MAX)).expect("trucating cast error")
1526-
}

src/terminator/intrinsics/ints.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,46 @@ pub fn bitreverse<'tcx>(
657657
Type::I8 => conv_i8!(bitreverse_u8(val)),
658658
Type::U16 => bitreverse_u16(val),
659659
Type::I16 => conv_i16!(bitreverse_u16(conv_u16!(val))),
660+
Type::U32 => call!(
661+
CallSite::builtin(
662+
"bitreverse_u32".into(),
663+
FnSig::new(&[Type::U32], Type::U32),
664+
true
665+
),
666+
[val]
667+
),
668+
Type::I32 => crate::casts::int_to_int(
669+
Type::U32,
670+
&Type::I32,
671+
call!(
672+
CallSite::builtin(
673+
"bitreverse_u32".into(),
674+
FnSig::new(&[Type::U32], Type::U32),
675+
true
676+
),
677+
[crate::casts::int_to_int(Type::I32, &Type::U32, val)]
678+
),
679+
),
680+
Type::U64 => call!(
681+
CallSite::builtin(
682+
"bitreverse_u64".into(),
683+
FnSig::new(&[Type::U64], Type::U64),
684+
true
685+
),
686+
[val]
687+
),
688+
Type::I64 => crate::casts::int_to_int(
689+
Type::U64,
690+
&Type::I64,
691+
call!(
692+
CallSite::builtin(
693+
"bitreverse_u64".into(),
694+
FnSig::new(&[Type::U64], Type::U64),
695+
true
696+
),
697+
[crate::casts::int_to_int(Type::I64, &Type::U64, val)]
698+
),
699+
),
660700
Type::U128 => call!(
661701
CallSite::builtin(
662702
"bitreverse_u128".into(),
@@ -677,6 +717,7 @@ pub fn bitreverse<'tcx>(
677717
[crate::casts::int_to_int(Type::I128, &Type::U128, val)]
678718
),
679719
),
720+
680721
_ => todo!("can't yet bitreverse {val_tpe:?}"),
681722
},
682723
ctx,

0 commit comments

Comments
 (0)