From 3e572511af26f5b469cbfded83069ca215c74740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 11 Jul 2013 19:31:38 +0200 Subject: [PATCH] Remove duplicated code from trans_intrinsics Most arms of the huge match contain the same code, differing only in small details like the name of the llvm intrinsic that is to be called. Thus the duplicated code can be factored out into a few functions that take some parameters to handle the differences. --- src/librustc/middle/trans/foreign.rs | 428 +++++++-------------------- 1 file changed, 109 insertions(+), 319 deletions(-) diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index edf003e3e52..6a38c41da0d 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -550,6 +550,64 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ref_id: Option) { debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); + fn simple_llvm_intrinsic(bcx: block, name: &'static str, num_args: uint) { + assert!(num_args <= 4); + let mut args = [0 as ValueRef, ..4]; + let first_real_arg = bcx.fcx.arg_pos(0u); + for uint::range(0, num_args) |i| { + args[i] = get_param(bcx.fcx.llfn, first_real_arg + i); + } + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Store(bcx, Call(bcx, llfn, args.slice(0, num_args)), bcx.fcx.llretptr.get()); + } + + fn memcpy_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); + } + + fn memset_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let val = get_param(decl, first_real_arg + 1); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + } + + fn count_zeros_intrinsic(bcx: block, name: &'static str) { + let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); + let y = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Store(bcx, Call(bcx, llfn, [x, y]), bcx.fcx.llretptr.get()) + } + let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id)); let fcx = new_fn_ctxt_w_id(ccx, @@ -800,325 +858,57 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); Store(bcx, morestack_addr, fcx.llretptr.get()); } - "memcpy32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memcpy64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memset32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "memset64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "sqrtf32" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f32"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "sqrtf64" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f64"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "powif32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f32"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "powif64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f64"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "sinf32" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f32"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "sinf64" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f64"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "cosf32" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f32"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "cosf64" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f64"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "powf32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f32"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "powf64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f64"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "expf32" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f32"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "expf64" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f64"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "exp2f32" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f32"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "exp2f64" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f64"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "logf32" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f32"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "logf64" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f64"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "log10f32" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f32"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log10f64" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f64"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log2f32" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f32"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "log2f64" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f64"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "fmaf32" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f32"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fmaf64" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f64"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fabsf32" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f32"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "fabsf64" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f64"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "floorf32" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f32"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "floorf64" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f64"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "ceilf32" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f32"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "ceilf64" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f64"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "truncf32" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f32"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "truncf64" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f64"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "ctpop8" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i8"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop16" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i16"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop32" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i32"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop64" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i64"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctlz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i8"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i16"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i32"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i64"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "cttz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i8"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i16"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i32"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i64"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "bswap16" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i16"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap32" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i32"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap64" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i64"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } + "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), + "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), + "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32), + "memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64), + "memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32), + "memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64), + "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1), + "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1), + "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2), + "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2), + "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1), + "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1), + "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1), + "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1), + "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2), + "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2), + "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1), + "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1), + "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1), + "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1), + "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1), + "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1), + "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1), + "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1), + "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1), + "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1), + "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3), + "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3), + "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1), + "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1), + "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1), + "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1), + "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1), + "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1), + "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1), + "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1), + "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1), + "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1), + "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1), + "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1), + "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"), + "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"), + "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"), + "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"), + "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"), + "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"), + "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"), + "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"), + "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1), + "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1), + "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1), _ => { // Could we make this an enum rather than a string? does it get // checked earlier?