Skip to content

Commit 0873553

Browse files
committed
Merge pull request #4298 from JensNockert/byteswap
Add support for byteswap intrinsics
2 parents 57c5999 + a51661e commit 0873553

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2446,6 +2446,12 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
24462446
T_fn(~[T_i32(), T_i1()], T_i32()));
24472447
let cttz64 = decl_cdecl_fn(llmod, ~"llvm.cttz.i64",
24482448
T_fn(~[T_i64(), T_i1()], T_i64()));
2449+
let bswap16 = decl_cdecl_fn(llmod, ~"llvm.bswap.i16",
2450+
T_fn(~[T_i16()], T_i16()));
2451+
let bswap32 = decl_cdecl_fn(llmod, ~"llvm.bswap.i32",
2452+
T_fn(~[T_i32()], T_i32()));
2453+
let bswap64 = decl_cdecl_fn(llmod, ~"llvm.bswap.i64",
2454+
T_fn(~[T_i64()], T_i64()));
24492455

24502456
let intrinsics = HashMap();
24512457
intrinsics.insert(~"llvm.gcroot", gcroot);
@@ -2498,6 +2504,9 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
24982504
intrinsics.insert(~"llvm.cttz.i16", cttz16);
24992505
intrinsics.insert(~"llvm.cttz.i32", cttz32);
25002506
intrinsics.insert(~"llvm.cttz.i64", cttz64);
2507+
intrinsics.insert(~"llvm.bswap.i16", bswap16);
2508+
intrinsics.insert(~"llvm.bswap.i32", bswap32);
2509+
intrinsics.insert(~"llvm.bswap.i64", bswap64);
25012510

25022511
return intrinsics;
25032512
}

src/librustc/middle/trans/foreign.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,21 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
12671267
let cttz = ccx.intrinsics.get(~"llvm.cttz.i64");
12681268
Store(bcx, Call(bcx, cttz, ~[x, y]), fcx.llretptr)
12691269
}
1270+
~"bswap16" => {
1271+
let x = get_param(decl, first_real_arg);
1272+
let cttz = ccx.intrinsics.get(~"llvm.bswap.i16");
1273+
Store(bcx, Call(bcx, cttz, ~[x]), fcx.llretptr)
1274+
}
1275+
~"bswap32" => {
1276+
let x = get_param(decl, first_real_arg);
1277+
let cttz = ccx.intrinsics.get(~"llvm.bswap.i32");
1278+
Store(bcx, Call(bcx, cttz, ~[x]), fcx.llretptr)
1279+
}
1280+
~"bswap64" => {
1281+
let x = get_param(decl, first_real_arg);
1282+
let cttz = ccx.intrinsics.get(~"llvm.bswap.i64");
1283+
Store(bcx, Call(bcx, cttz, ~[x]), fcx.llretptr)
1284+
}
12701285
_ => {
12711286
// Could we make this an enum rather than a string? does it get
12721287
// checked earlier?

src/librustc/middle/trans/type_use.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
140140
~"ctlz8" | ~"ctlz16" | ~"ctlz32" | ~"ctlz64" => 0,
141141
~"cttz8" | ~"cttz16" | ~"cttz32" | ~"cttz64" => 0,
142142

143+
~"bswap16" | ~"bswap32" | ~"bswap64" => 0,
144+
143145
// would be cool to make these an enum instead of strings!
144146
_ => fail ~"unknown intrinsic in type_use"
145147
};

src/librustc/middle/typeck/check/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,6 +3224,18 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
32243224
(0u, ~[arg(ast::by_copy, ty::mk_i64(tcx))],
32253225
ty::mk_i64(tcx))
32263226
}
3227+
~"bswap16" => {
3228+
(0u, ~[arg(ast::by_copy, ty::mk_i16(tcx))],
3229+
ty::mk_i16(tcx))
3230+
}
3231+
~"bswap32" => {
3232+
(0u, ~[arg(ast::by_copy, ty::mk_i32(tcx))],
3233+
ty::mk_i32(tcx))
3234+
}
3235+
~"bswap64" => {
3236+
(0u, ~[arg(ast::by_copy, ty::mk_i64(tcx))],
3237+
ty::mk_i64(tcx))
3238+
}
32273239
ref other => {
32283240
tcx.sess.span_err(it.span, ~"unrecognized intrinsic function: `" +
32293241
(*other) + ~"`");

src/test/run-pass/intrinsics-integer.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ extern mod rusti {
2828
fn cttz16(x: i16) -> i16;
2929
fn cttz32(x: i32) -> i32;
3030
fn cttz64(x: i64) -> i64;
31+
32+
fn bswap16(x: i16) -> i16;
33+
fn bswap32(x: i32) -> i32;
34+
fn bswap64(x: i64) -> i64;
3135
}
3236

3337
fn main() {
@@ -109,4 +113,8 @@ fn main() {
109113
assert(cttz32(-1i32) == 0i32);
110114
assert(cttz64(-1i64) == 0i64);
111115

116+
assert(bswap16(0x0A0Bi16) == 0x0B0Ai16);
117+
assert(bswap32(0x0ABBCC0Di32) == 0x0DCCBB0Ai32);
118+
assert(bswap64(0x0122334455667708i64) == 0x0877665544332201i64);
119+
112120
}

0 commit comments

Comments
 (0)