Implement bswap intrinsic

This commit is contained in:
bjorn3 2018-11-17 18:52:47 +01:00
parent d425116bdc
commit db5ffdedf7
4 changed files with 89 additions and 25 deletions

View File

@ -208,6 +208,16 @@ impl PartialEq for u32 {
}
}
impl PartialEq for u64 {
fn eq(&self, other: &u64) -> bool {
(*self) == (*other)
}
fn ne(&self, other: &u64) -> bool {
(*self) != (*other)
}
}
impl PartialEq for usize {
fn eq(&self, other: &usize) -> bool {
(*self) == (*other)
@ -375,6 +385,7 @@ pub mod intrinsics {
pub fn ctlz_nonzero<T>(x: T) -> T;
pub fn needs_drop<T>() -> bool;
pub fn bitreverse<T>(x: T) -> T;
pub fn bswap<T>(x: T) -> T;
}
}

View File

@ -139,6 +139,11 @@ fn main() {
assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8);
assert_eq!(intrinsics::bswap(0xabu8), 0xabu8);
assert_eq!(intrinsics::bswap(0xddccu16), 0xccddu16);
assert_eq!(intrinsics::bswap(0xffee_ddccu32), 0xccdd_eeffu32);
assert_eq!(intrinsics::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64);
assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
let chars = &['C', 'h', 'a', 'r', 's'];

View File

@ -1,25 +0,0 @@
From da996dae0b95f986de46a916aca00e03257ba4f9 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Wed, 30 Jan 2019 14:51:57 +0100
Subject: [PATCH] Patch away bswap usage
---
src/libcore/num/mod.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index f928d40..6a146f5 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -2303,7 +2303,7 @@ assert_eq!(m, ", $swapped, ");
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn swap_bytes(self) -> Self {
- intrinsics::bswap(self as $ActualT) as Self
+ 42 // bswap is unsupported by cg_clif
}
}
--
2.11.0

View File

@ -415,6 +415,79 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
let res = CValue::by_val(fx.bcx.ins().bitrev(arg), fx.layout_of(T));
ret.write_cvalue(fx, res);
};
bswap, <T> (v arg) {
// FIXME(CraneStation/cranelift#794) add bswap instruction to cranelift
fn swap(bcx: &mut FunctionBuilder, v: Value) -> Value {
match bcx.func.dfg.value_type(v) {
types::I8 => v,
// https://code.woboq.org/gcc/include/bits/byteswap.h.html
types::I16 => {
let tmp1 = bcx.ins().ishl_imm(v, 8);
let n1 = bcx.ins().band_imm(tmp1, 0xFF00);
let tmp2 = bcx.ins().ushr_imm(v, 8);
let n2 = bcx.ins().band_imm(tmp2, 0x00FF);
bcx.ins().bor(n1, n2)
}
types::I32 => {
let tmp1 = bcx.ins().ishl_imm(v, 24);
let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000);
let tmp2 = bcx.ins().ishl_imm(v, 8);
let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000);
let tmp3 = bcx.ins().ushr_imm(v, 8);
let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00);
let tmp4 = bcx.ins().ushr_imm(v, 24);
let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF);
let or_tmp1 = bcx.ins().bor(n1, n2);
let or_tmp2 = bcx.ins().bor(n3, n4);
bcx.ins().bor(or_tmp1, or_tmp2)
}
types::I64 => {
let tmp1 = bcx.ins().ishl_imm(v, 56);
let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000_0000_0000u64 as i64);
let tmp2 = bcx.ins().ishl_imm(v, 40);
let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000_0000_0000u64 as i64);
let tmp3 = bcx.ins().ishl_imm(v, 24);
let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00_0000_0000u64 as i64);
let tmp4 = bcx.ins().ishl_imm(v, 8);
let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF_0000_0000u64 as i64);
let tmp5 = bcx.ins().ushr_imm(v, 8);
let n5 = bcx.ins().band_imm(tmp5, 0x0000_0000_FF00_0000u64 as i64);
let tmp6 = bcx.ins().ushr_imm(v, 24);
let n6 = bcx.ins().band_imm(tmp6, 0x0000_0000_00FF_0000u64 as i64);
let tmp7 = bcx.ins().ushr_imm(v, 40);
let n7 = bcx.ins().band_imm(tmp7, 0x0000_0000_0000_FF00u64 as i64);
let tmp8 = bcx.ins().ushr_imm(v, 56);
let n8 = bcx.ins().band_imm(tmp8, 0x0000_0000_0000_00FFu64 as i64);
let or_tmp1 = bcx.ins().bor(n1, n2);
let or_tmp2 = bcx.ins().bor(n3, n4);
let or_tmp3 = bcx.ins().bor(n5, n6);
let or_tmp4 = bcx.ins().bor(n7, n8);
let or_tmp5 = bcx.ins().bor(or_tmp1, or_tmp2);
let or_tmp6 = bcx.ins().bor(or_tmp3, or_tmp4);
bcx.ins().bor(or_tmp5, or_tmp6)
}
ty => unimplemented!("bwap {}", ty),
}
};
let res = CValue::by_val(swap(&mut fx.bcx, arg), fx.layout_of(T));
ret.write_cvalue(fx, res);
};
needs_drop, <T> () {
let needs_drop = if T.needs_drop(fx.tcx, ParamEnv::reveal_all()) {
1