Skip to content

Commit db5ffde

Browse files
committed
Implement bswap intrinsic
1 parent d425116 commit db5ffde

File tree

4 files changed

+89
-25
lines changed

4 files changed

+89
-25
lines changed

example/mini_core.rs

+11
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ impl PartialEq for u32 {
208208
}
209209
}
210210

211+
212+
impl PartialEq for u64 {
213+
fn eq(&self, other: &u64) -> bool {
214+
(*self) == (*other)
215+
}
216+
fn ne(&self, other: &u64) -> bool {
217+
(*self) != (*other)
218+
}
219+
}
220+
211221
impl PartialEq for usize {
212222
fn eq(&self, other: &usize) -> bool {
213223
(*self) == (*other)
@@ -375,6 +385,7 @@ pub mod intrinsics {
375385
pub fn ctlz_nonzero<T>(x: T) -> T;
376386
pub fn needs_drop<T>() -> bool;
377387
pub fn bitreverse<T>(x: T) -> T;
388+
pub fn bswap<T>(x: T) -> T;
378389
}
379390
}
380391

example/mini_core_hello_world.rs

+5
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ fn main() {
139139

140140
assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8);
141141

142+
assert_eq!(intrinsics::bswap(0xabu8), 0xabu8);
143+
assert_eq!(intrinsics::bswap(0xddccu16), 0xccddu16);
144+
assert_eq!(intrinsics::bswap(0xffee_ddccu32), 0xccdd_eeffu32);
145+
assert_eq!(intrinsics::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64);
146+
142147
assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
143148

144149
let chars = &['C', 'h', 'a', 'r', 's'];

patches/0013-Patch-away-bswap-usage.patch

-25
This file was deleted.

src/intrinsics.rs

+73
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,79 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
415415
let res = CValue::by_val(fx.bcx.ins().bitrev(arg), fx.layout_of(T));
416416
ret.write_cvalue(fx, res);
417417
};
418+
bswap, <T> (v arg) {
419+
// FIXME(CraneStation/cranelift#794) add bswap instruction to cranelift
420+
fn swap(bcx: &mut FunctionBuilder, v: Value) -> Value {
421+
match bcx.func.dfg.value_type(v) {
422+
types::I8 => v,
423+
424+
// https://code.woboq.org/gcc/include/bits/byteswap.h.html
425+
types::I16 => {
426+
let tmp1 = bcx.ins().ishl_imm(v, 8);
427+
let n1 = bcx.ins().band_imm(tmp1, 0xFF00);
428+
429+
let tmp2 = bcx.ins().ushr_imm(v, 8);
430+
let n2 = bcx.ins().band_imm(tmp2, 0x00FF);
431+
432+
bcx.ins().bor(n1, n2)
433+
}
434+
types::I32 => {
435+
let tmp1 = bcx.ins().ishl_imm(v, 24);
436+
let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000);
437+
438+
let tmp2 = bcx.ins().ishl_imm(v, 8);
439+
let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000);
440+
441+
let tmp3 = bcx.ins().ushr_imm(v, 8);
442+
let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00);
443+
444+
let tmp4 = bcx.ins().ushr_imm(v, 24);
445+
let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF);
446+
447+
let or_tmp1 = bcx.ins().bor(n1, n2);
448+
let or_tmp2 = bcx.ins().bor(n3, n4);
449+
bcx.ins().bor(or_tmp1, or_tmp2)
450+
}
451+
types::I64 => {
452+
let tmp1 = bcx.ins().ishl_imm(v, 56);
453+
let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000_0000_0000u64 as i64);
454+
455+
let tmp2 = bcx.ins().ishl_imm(v, 40);
456+
let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000_0000_0000u64 as i64);
457+
458+
let tmp3 = bcx.ins().ishl_imm(v, 24);
459+
let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00_0000_0000u64 as i64);
460+
461+
let tmp4 = bcx.ins().ishl_imm(v, 8);
462+
let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF_0000_0000u64 as i64);
463+
464+
let tmp5 = bcx.ins().ushr_imm(v, 8);
465+
let n5 = bcx.ins().band_imm(tmp5, 0x0000_0000_FF00_0000u64 as i64);
466+
467+
let tmp6 = bcx.ins().ushr_imm(v, 24);
468+
let n6 = bcx.ins().band_imm(tmp6, 0x0000_0000_00FF_0000u64 as i64);
469+
470+
let tmp7 = bcx.ins().ushr_imm(v, 40);
471+
let n7 = bcx.ins().band_imm(tmp7, 0x0000_0000_0000_FF00u64 as i64);
472+
473+
let tmp8 = bcx.ins().ushr_imm(v, 56);
474+
let n8 = bcx.ins().band_imm(tmp8, 0x0000_0000_0000_00FFu64 as i64);
475+
476+
let or_tmp1 = bcx.ins().bor(n1, n2);
477+
let or_tmp2 = bcx.ins().bor(n3, n4);
478+
let or_tmp3 = bcx.ins().bor(n5, n6);
479+
let or_tmp4 = bcx.ins().bor(n7, n8);
480+
481+
let or_tmp5 = bcx.ins().bor(or_tmp1, or_tmp2);
482+
let or_tmp6 = bcx.ins().bor(or_tmp3, or_tmp4);
483+
bcx.ins().bor(or_tmp5, or_tmp6)
484+
}
485+
ty => unimplemented!("bwap {}", ty),
486+
}
487+
};
488+
let res = CValue::by_val(swap(&mut fx.bcx, arg), fx.layout_of(T));
489+
ret.write_cvalue(fx, res);
490+
};
418491
needs_drop, <T> () {
419492
let needs_drop = if T.needs_drop(fx.tcx, ParamEnv::reveal_all()) {
420493
1

0 commit comments

Comments
 (0)