Implement bswap intrinsic
This commit is contained in:
parent
d425116bdc
commit
db5ffdedf7
4 changed files with 89 additions and 25 deletions
|
@ -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 {
|
impl PartialEq for usize {
|
||||||
fn eq(&self, other: &usize) -> bool {
|
fn eq(&self, other: &usize) -> bool {
|
||||||
(*self) == (*other)
|
(*self) == (*other)
|
||||||
|
@ -375,6 +385,7 @@ pub mod intrinsics {
|
||||||
pub fn ctlz_nonzero<T>(x: T) -> T;
|
pub fn ctlz_nonzero<T>(x: T) -> T;
|
||||||
pub fn needs_drop<T>() -> bool;
|
pub fn needs_drop<T>() -> bool;
|
||||||
pub fn bitreverse<T>(x: T) -> T;
|
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::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);
|
assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
|
||||||
|
|
||||||
let chars = &['C', 'h', 'a', 'r', 's'];
|
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));
|
let res = CValue::by_val(fx.bcx.ins().bitrev(arg), fx.layout_of(T));
|
||||||
ret.write_cvalue(fx, res);
|
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> () {
|
needs_drop, <T> () {
|
||||||
let needs_drop = if T.needs_drop(fx.tcx, ParamEnv::reveal_all()) {
|
let needs_drop = if T.needs_drop(fx.tcx, ParamEnv::reveal_all()) {
|
||||||
1
|
1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue