Implement bswap intrinsic
This commit is contained in:
parent
d425116bdc
commit
db5ffdedf7
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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'];
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user