// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(dead_code)] // FFI wrappers
#![allow(non_snake_case)]

use llvm;
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{Opcode, IntPredicate, RealPredicate};
use llvm::{ValueRef, BasicBlockRef};
use common::*;
use syntax_pos::Span;

use builder::Builder;
use type_::Type;
use value::Value;
use debuginfo::DebugLoc;

use libc::{c_uint, c_char};

pub fn terminate(cx: Block, _: &str) {
    debug!("terminate({})", cx.to_str());
    cx.terminated.set(true);
}

pub fn check_not_terminated(cx: Block) {
    if cx.terminated.get() {
        bug!("already terminated!");
    }
}

pub fn B<'blk, 'tcx>(cx: Block<'blk, 'tcx>) -> Builder<'blk, 'tcx> {
    let b = cx.fcx.ccx.builder();
    b.position_at_end(cx.llbb);
    b
}

// The difference between a block being unreachable and being terminated is
// somewhat obscure, and has to do with error checking. When a block is
// terminated, we're saying that trying to add any further statements in the
// block is an error. On the other hand, if something is unreachable, that
// means that the block was terminated in some way that we don't want to check
// for (panic/break/return statements, call to diverging functions, etc), and
// further instructions to the block should simply be ignored.

pub fn RetVoid(cx: Block, debug_loc: DebugLoc) {
    if cx.unreachable.get() {
        return;
    }
    check_not_terminated(cx);
    terminate(cx, "RetVoid");
    debug_loc.apply(cx.fcx);
    B(cx).ret_void();
}

pub fn Ret(cx: Block, v: ValueRef, debug_loc: DebugLoc) {
    if cx.unreachable.get() {
        return;
    }
    check_not_terminated(cx);
    terminate(cx, "Ret");
    debug_loc.apply(cx.fcx);
    B(cx).ret(v);
}

pub fn AggregateRet(cx: Block,
                    ret_vals: &[ValueRef],
                    debug_loc: DebugLoc) {
    if cx.unreachable.get() {
        return;
    }
    check_not_terminated(cx);
    terminate(cx, "AggregateRet");
    debug_loc.apply(cx.fcx);
    B(cx).aggregate_ret(ret_vals);
}

pub fn Br(cx: Block, dest: BasicBlockRef, debug_loc: DebugLoc) {
    if cx.unreachable.get() {
        return;
    }
    check_not_terminated(cx);
    terminate(cx, "Br");
    debug_loc.apply(cx.fcx);
    B(cx).br(dest);
}

pub fn CondBr(cx: Block,
              if_: ValueRef,
              then: BasicBlockRef,
              else_: BasicBlockRef,
              debug_loc: DebugLoc) {
    if cx.unreachable.get() {
        return;
    }
    check_not_terminated(cx);
    terminate(cx, "CondBr");
    debug_loc.apply(cx.fcx);
    B(cx).cond_br(if_, then, else_);
}

pub fn Switch(cx: Block, v: ValueRef, else_: BasicBlockRef, num_cases: usize)
    -> ValueRef {
    if cx.unreachable.get() { return _Undef(v); }
    check_not_terminated(cx);
    terminate(cx, "Switch");
    B(cx).switch(v, else_, num_cases)
}

pub fn AddCase(s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) {
    unsafe {
        if llvm::LLVMIsUndef(s) == llvm::True { return; }
        llvm::LLVMAddCase(s, on_val, dest);
    }
}

pub fn IndirectBr(cx: Block,
                  addr: ValueRef,
                  num_dests: usize,
                  debug_loc: DebugLoc) {
    if cx.unreachable.get() {
        return;
    }
    check_not_terminated(cx);
    terminate(cx, "IndirectBr");
    debug_loc.apply(cx.fcx);
    B(cx).indirect_br(addr, num_dests);
}

pub fn Invoke(cx: Block,
              fn_: ValueRef,
              args: &[ValueRef],
              then: BasicBlockRef,
              catch: BasicBlockRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return C_null(Type::i8(cx.ccx()));
    }
    check_not_terminated(cx);
    terminate(cx, "Invoke");
    debug!("Invoke({:?} with arguments ({}))",
           Value(fn_),
           args.iter().map(|a| {
                format!("{:?}", Value(*a))
           }).collect::<Vec<String>>().join(", "));
    debug_loc.apply(cx.fcx);
    let bundle = cx.lpad().and_then(|b| b.bundle());
    B(cx).invoke(fn_, args, then, catch, bundle)
}

pub fn Unreachable(cx: Block) {
    if cx.unreachable.get() {
        return
    }
    cx.unreachable.set(true);
    if !cx.terminated.get() {
        B(cx).unreachable();
    }
}

pub fn _Undef(val: ValueRef) -> ValueRef {
    unsafe {
        return llvm::LLVMGetUndef(val_ty(val).to_ref());
    }
}

/* Arithmetic */
pub fn Add(cx: Block,
           lhs: ValueRef,
           rhs: ValueRef,
           debug_loc: DebugLoc)
           -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).add(lhs, rhs)
}

pub fn NSWAdd(cx: Block,
              lhs: ValueRef,
              rhs: ValueRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nswadd(lhs, rhs)
}

pub fn NUWAdd(cx: Block,
              lhs: ValueRef,
              rhs: ValueRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nuwadd(lhs, rhs)
}

pub fn FAdd(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fadd(lhs, rhs)
}

pub fn FAddFast(cx: Block,
                lhs: ValueRef,
                rhs: ValueRef,
                debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fadd_fast(lhs, rhs)
}

pub fn Sub(cx: Block,
           lhs: ValueRef,
           rhs: ValueRef,
           debug_loc: DebugLoc)
           -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).sub(lhs, rhs)
}

pub fn NSWSub(cx: Block,
              lhs: ValueRef,
              rhs: ValueRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nswsub(lhs, rhs)
}

pub fn NUWSub(cx: Block,
              lhs: ValueRef,
              rhs: ValueRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nuwsub(lhs, rhs)
}

pub fn FSub(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fsub(lhs, rhs)
}

pub fn FSubFast(cx: Block,
                lhs: ValueRef,
                rhs: ValueRef,
                debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fsub_fast(lhs, rhs)
}

pub fn Mul(cx: Block,
           lhs: ValueRef,
           rhs: ValueRef,
           debug_loc: DebugLoc)
           -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).mul(lhs, rhs)
}

pub fn NSWMul(cx: Block,
              lhs: ValueRef,
              rhs: ValueRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nswmul(lhs, rhs)
}

pub fn NUWMul(cx: Block,
              lhs: ValueRef,
              rhs: ValueRef,
              debug_loc: DebugLoc)
              -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nuwmul(lhs, rhs)
}

pub fn FMul(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fmul(lhs, rhs)
}

pub fn FMulFast(cx: Block,
                lhs: ValueRef,
                rhs: ValueRef,
                debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fmul_fast(lhs, rhs)
}

pub fn UDiv(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).udiv(lhs, rhs)
}

pub fn SDiv(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).sdiv(lhs, rhs)
}

pub fn ExactSDiv(cx: Block,
                 lhs: ValueRef,
                 rhs: ValueRef,
                 debug_loc: DebugLoc)
                 -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).exactsdiv(lhs, rhs)
}

pub fn FDiv(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fdiv(lhs, rhs)
}

pub fn FDivFast(cx: Block,
                lhs: ValueRef,
                rhs: ValueRef,
                debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fdiv_fast(lhs, rhs)
}

pub fn URem(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).urem(lhs, rhs)
}

pub fn SRem(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).srem(lhs, rhs)
}

pub fn FRem(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).frem(lhs, rhs)
}

pub fn FRemFast(cx: Block,
                lhs: ValueRef,
                rhs: ValueRef,
                debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).frem_fast(lhs, rhs)
}

pub fn Shl(cx: Block,
           lhs: ValueRef,
           rhs: ValueRef,
           debug_loc: DebugLoc)
           -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).shl(lhs, rhs)
}

pub fn LShr(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).lshr(lhs, rhs)
}

pub fn AShr(cx: Block,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).ashr(lhs, rhs)
}

pub fn And(cx: Block,
           lhs: ValueRef,
           rhs: ValueRef,
           debug_loc: DebugLoc)
           -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).and(lhs, rhs)
}

pub fn Or(cx: Block,
          lhs: ValueRef,
          rhs: ValueRef,
          debug_loc: DebugLoc)
          -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).or(lhs, rhs)
}

pub fn Xor(cx: Block,
           lhs: ValueRef,
           rhs: ValueRef,
           debug_loc: DebugLoc)
           -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).xor(lhs, rhs)
}

pub fn BinOp(cx: Block,
             op: Opcode,
             lhs: ValueRef,
             rhs: ValueRef,
             debug_loc: DebugLoc)
          -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(lhs);
    }
    debug_loc.apply(cx.fcx);
    B(cx).binop(op, lhs, rhs)
}

pub fn Neg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(v);
    }
    debug_loc.apply(cx.fcx);
    B(cx).neg(v)
}

pub fn NSWNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(v);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nswneg(v)
}

pub fn NUWNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(v);
    }
    debug_loc.apply(cx.fcx);
    B(cx).nuwneg(v)
}
pub fn FNeg(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(v);
    }
    debug_loc.apply(cx.fcx);
    B(cx).fneg(v)
}

pub fn Not(cx: Block, v: ValueRef, debug_loc: DebugLoc) -> ValueRef {
    if cx.unreachable.get() {
        return _Undef(v);
    }
    debug_loc.apply(cx.fcx);
    B(cx).not(v)
}

pub fn Alloca(cx: Block, ty: Type, name: &str) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(ty.ptr_to().to_ref()); }
        AllocaFcx(cx.fcx, ty, name)
    }
}

pub fn AllocaFcx(fcx: &FunctionContext, ty: Type, name: &str) -> ValueRef {
    let b = fcx.ccx.builder();
    b.position_before(fcx.alloca_insert_pt.get().unwrap());
    DebugLoc::None.apply(fcx);
    b.alloca(ty, name)
}

pub fn Free(cx: Block, pointer_val: ValueRef) {
    if cx.unreachable.get() { return; }
    B(cx).free(pointer_val)
}

pub fn Load(cx: Block, pointer_val: ValueRef) -> ValueRef {
    unsafe {
        let ccx = cx.fcx.ccx;
        if cx.unreachable.get() {
            let ty = val_ty(pointer_val);
            let eltty = if ty.kind() == llvm::Array {
                ty.element_type()
            } else {
                ccx.int_type()
            };
            return llvm::LLVMGetUndef(eltty.to_ref());
        }
        B(cx).load(pointer_val)
    }
}

pub fn VolatileLoad(cx: Block, pointer_val: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).volatile_load(pointer_val)
    }
}

pub fn AtomicLoad(cx: Block, pointer_val: ValueRef, order: AtomicOrdering) -> ValueRef {
    unsafe {
        let ccx = cx.fcx.ccx;
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(ccx.int_type().to_ref());
        }
        B(cx).atomic_load(pointer_val, order)
    }
}


pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: u64,
                       hi: u64, signed: llvm::Bool) -> ValueRef {
    if cx.unreachable.get() {
        let ccx = cx.fcx.ccx;
        let ty = val_ty(pointer_val);
        let eltty = if ty.kind() == llvm::Array {
            ty.element_type()
        } else {
            ccx.int_type()
        };
        unsafe {
            llvm::LLVMGetUndef(eltty.to_ref())
        }
    } else {
        B(cx).load_range_assert(pointer_val, lo, hi, signed)
    }
}

pub fn LoadNonNull(cx: Block, ptr: ValueRef) -> ValueRef {
    if cx.unreachable.get() {
        let ccx = cx.fcx.ccx;
        let ty = val_ty(ptr);
        let eltty = if ty.kind() == llvm::Array {
            ty.element_type()
        } else {
            ccx.int_type()
        };
        unsafe {
            llvm::LLVMGetUndef(eltty.to_ref())
        }
    } else {
        B(cx).load_nonnull(ptr)
    }
}

pub fn Store(cx: Block, val: ValueRef, ptr: ValueRef) -> ValueRef {
    if cx.unreachable.get() { return C_nil(cx.ccx()); }
    B(cx).store(val, ptr)
}

pub fn VolatileStore(cx: Block, val: ValueRef, ptr: ValueRef) -> ValueRef {
    if cx.unreachable.get() { return C_nil(cx.ccx()); }
    B(cx).volatile_store(val, ptr)
}

pub fn AtomicStore(cx: Block, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
    if cx.unreachable.get() { return; }
    B(cx).atomic_store(val, ptr, order)
}

pub fn GEP(cx: Block, pointer: ValueRef, indices: &[ValueRef]) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).ptr_to().to_ref());
        }
        B(cx).gep(pointer, indices)
    }
}

// Simple wrapper around GEP that takes an array of ints and wraps them
// in C_i32()
#[inline]
pub fn GEPi(cx: Block, base: ValueRef, ixs: &[usize]) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).ptr_to().to_ref());
        }
        B(cx).gepi(base, ixs)
    }
}

pub fn InBoundsGEP(cx: Block, pointer: ValueRef, indices: &[ValueRef]) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).ptr_to().to_ref());
        }
        B(cx).inbounds_gep(pointer, indices)
    }
}

pub fn StructGEP(cx: Block, pointer: ValueRef, idx: usize) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).ptr_to().to_ref());
        }
        B(cx).struct_gep(pointer, idx)
    }
}

pub fn GlobalString(cx: Block, _str: *const c_char) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::i8p(cx.ccx()).to_ref());
        }
        B(cx).global_string(_str)
    }
}

pub fn GlobalStringPtr(cx: Block, _str: *const c_char) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::i8p(cx.ccx()).to_ref());
        }
        B(cx).global_string_ptr(_str)
    }
}

/* Casts */
pub fn Trunc(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).trunc(val, dest_ty)
    }
}

pub fn ZExt(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).zext(val, dest_ty)
    }
}

pub fn SExt(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).sext(val, dest_ty)
    }
}

pub fn FPToUI(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).fptoui(val, dest_ty)
    }
}

pub fn FPToSI(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).fptosi(val, dest_ty)
    }
}

pub fn UIToFP(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).uitofp(val, dest_ty)
    }
}

pub fn SIToFP(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).sitofp(val, dest_ty)
    }
}

pub fn FPTrunc(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).fptrunc(val, dest_ty)
    }
}

pub fn FPExt(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).fpext(val, dest_ty)
    }
}

pub fn PtrToInt(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).ptrtoint(val, dest_ty)
    }
}

pub fn IntToPtr(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).inttoptr(val, dest_ty)
    }
}

pub fn BitCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).bitcast(val, dest_ty)
    }
}

pub fn ZExtOrBitCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).zext_or_bitcast(val, dest_ty)
    }
}

pub fn SExtOrBitCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).sext_or_bitcast(val, dest_ty)
    }
}

pub fn TruncOrBitCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).trunc_or_bitcast(val, dest_ty)
    }
}

pub fn Cast(cx: Block, op: Opcode, val: ValueRef, dest_ty: Type,
            _: *const u8)
     -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).cast(op, val, dest_ty)
    }
}

pub fn PointerCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).pointercast(val, dest_ty)
    }
}

pub fn IntCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).intcast(val, dest_ty)
    }
}

pub fn FPCast(cx: Block, val: ValueRef, dest_ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(dest_ty.to_ref()); }
        B(cx).fpcast(val, dest_ty)
    }
}


/* Comparisons */
pub fn ICmp(cx: Block,
            op: IntPredicate,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::i1(cx.ccx()).to_ref());
        }
        debug_loc.apply(cx.fcx);
        B(cx).icmp(op, lhs, rhs)
    }
}

pub fn FCmp(cx: Block,
            op: RealPredicate,
            lhs: ValueRef,
            rhs: ValueRef,
            debug_loc: DebugLoc)
            -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::i1(cx.ccx()).to_ref());
        }
        debug_loc.apply(cx.fcx);
        B(cx).fcmp(op, lhs, rhs)
    }
}

/* Miscellaneous instructions */
pub fn EmptyPhi(cx: Block, ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(ty.to_ref()); }
        B(cx).empty_phi(ty)
    }
}

pub fn Phi(cx: Block, ty: Type, vals: &[ValueRef],
           bbs: &[BasicBlockRef]) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(ty.to_ref()); }
        B(cx).phi(ty, vals, bbs)
    }
}

pub fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
    unsafe {
        if llvm::LLVMIsUndef(phi) == llvm::True { return; }
        llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
    }
}

pub fn _UndefReturn(cx: Block, fn_: ValueRef) -> ValueRef {
    unsafe {
        let ccx = cx.fcx.ccx;
        let ty = val_ty(fn_);
        let retty = if ty.kind() == llvm::Function {
            ty.return_type()
        } else {
            ccx.int_type()
        };
        B(cx).count_insn("ret_undef");
        llvm::LLVMGetUndef(retty.to_ref())
    }
}

pub fn add_span_comment(cx: Block, sp: Span, text: &str) {
    B(cx).add_span_comment(sp, text)
}

pub fn add_comment(cx: Block, text: &str) {
    B(cx).add_comment(text)
}

pub fn InlineAsmCall(cx: Block, asm: *const c_char, cons: *const c_char,
                     inputs: &[ValueRef], output: Type,
                     volatile: bool, alignstack: bool,
                     dia: AsmDialect) -> ValueRef {
    B(cx).inline_asm_call(asm, cons, inputs, output, volatile, alignstack, dia)
}

pub fn Call(cx: Block,
            fn_: ValueRef,
            args: &[ValueRef],
            debug_loc: DebugLoc)
            -> ValueRef {
    if cx.unreachable.get() {
        return _UndefReturn(cx, fn_);
    }
    debug_loc.apply(cx.fcx);
    let bundle = cx.lpad.get().and_then(|b| b.bundle());
    B(cx).call(fn_, args, bundle)
}

pub fn AtomicFence(cx: Block, order: AtomicOrdering, scope: SynchronizationScope) {
    if cx.unreachable.get() { return; }
    B(cx).atomic_fence(order, scope)
}

pub fn Select(cx: Block, if_: ValueRef, then: ValueRef, else_: ValueRef) -> ValueRef {
    if cx.unreachable.get() { return _Undef(then); }
    B(cx).select(if_, then, else_)
}

pub fn VAArg(cx: Block, list: ValueRef, ty: Type) -> ValueRef {
    unsafe {
        if cx.unreachable.get() { return llvm::LLVMGetUndef(ty.to_ref()); }
        B(cx).va_arg(list, ty)
    }
}

pub fn ExtractElement(cx: Block, vec_val: ValueRef, index: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).extract_element(vec_val, index)
    }
}

pub fn InsertElement(cx: Block, vec_val: ValueRef, elt_val: ValueRef,
                     index: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).insert_element(vec_val, elt_val, index)
    }
}

pub fn ShuffleVector(cx: Block, v1: ValueRef, v2: ValueRef,
                     mask: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).shuffle_vector(v1, v2, mask)
    }
}

pub fn VectorSplat(cx: Block, num_elts: usize, elt_val: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).vector_splat(num_elts, elt_val)
    }
}

pub fn ExtractValue(cx: Block, agg_val: ValueRef, index: usize) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).extract_value(agg_val, index)
    }
}

pub fn InsertValue(cx: Block, agg_val: ValueRef, elt_val: ValueRef, index: usize) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
        }
        B(cx).insert_value(agg_val, elt_val, index)
    }
}

pub fn IsNull(cx: Block, val: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::i1(cx.ccx()).to_ref());
        }
        B(cx).is_null(val)
    }
}

pub fn IsNotNull(cx: Block, val: ValueRef) -> ValueRef {
    unsafe {
        if cx.unreachable.get() {
            return llvm::LLVMGetUndef(Type::i1(cx.ccx()).to_ref());
        }
        B(cx).is_not_null(val)
    }
}

pub fn PtrDiff(cx: Block, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
    unsafe {
        let ccx = cx.fcx.ccx;
        if cx.unreachable.get() { return llvm::LLVMGetUndef(ccx.int_type().to_ref()); }
        B(cx).ptrdiff(lhs, rhs)
    }
}

pub fn Trap(cx: Block) {
    if cx.unreachable.get() { return; }
    B(cx).trap();
}

pub fn LandingPad(cx: Block, ty: Type, pers_fn: ValueRef,
                  num_clauses: usize) -> ValueRef {
    check_not_terminated(cx);
    assert!(!cx.unreachable.get());
    B(cx).landing_pad(ty, pers_fn, num_clauses, cx.fcx.llfn)
}

pub fn AddClause(cx: Block, landing_pad: ValueRef, clause: ValueRef) {
    B(cx).add_clause(landing_pad, clause)
}

pub fn SetCleanup(cx: Block, landing_pad: ValueRef) {
    B(cx).set_cleanup(landing_pad)
}

pub fn SetPersonalityFn(cx: Block, f: ValueRef) {
    B(cx).set_personality_fn(f)
}

pub fn Resume(cx: Block, exn: ValueRef) -> ValueRef {
    check_not_terminated(cx);
    terminate(cx, "Resume");
    B(cx).resume(exn)
}

// Atomic Operations
pub fn AtomicCmpXchg(cx: Block, dst: ValueRef,
                     cmp: ValueRef, src: ValueRef,
                     order: AtomicOrdering,
                     failure_order: AtomicOrdering,
                     weak: llvm::Bool) -> ValueRef {
    B(cx).atomic_cmpxchg(dst, cmp, src, order, failure_order, weak)
}
pub fn AtomicRMW(cx: Block, op: AtomicRmwBinOp,
                 dst: ValueRef, src: ValueRef,
                 order: AtomicOrdering) -> ValueRef {
    B(cx).atomic_rmw(op, dst, src, order)
}

pub fn CleanupPad(cx: Block,
                  parent: Option<ValueRef>,
                  args: &[ValueRef]) -> ValueRef {
    check_not_terminated(cx);
    assert!(!cx.unreachable.get());
    B(cx).cleanup_pad(parent, args)
}

pub fn CleanupRet(cx: Block,
                  cleanup: ValueRef,
                  unwind: Option<BasicBlockRef>) -> ValueRef {
    check_not_terminated(cx);
    terminate(cx, "CleanupRet");
    B(cx).cleanup_ret(cleanup, unwind)
}

pub fn CatchPad(cx: Block,
                parent: ValueRef,
                args: &[ValueRef]) -> ValueRef {
    check_not_terminated(cx);
    assert!(!cx.unreachable.get());
    B(cx).catch_pad(parent, args)
}

pub fn CatchRet(cx: Block, pad: ValueRef, unwind: BasicBlockRef) -> ValueRef {
    check_not_terminated(cx);
    terminate(cx, "CatchRet");
    B(cx).catch_ret(pad, unwind)
}

pub fn CatchSwitch(cx: Block,
                   parent: Option<ValueRef>,
                   unwind: Option<BasicBlockRef>,
                   num_handlers: usize) -> ValueRef {
    check_not_terminated(cx);
    terminate(cx, "CatchSwitch");
    B(cx).catch_switch(parent, unwind, num_handlers)
}

pub fn AddHandler(cx: Block, catch_switch: ValueRef, handler: BasicBlockRef) {
    B(cx).add_handler(catch_switch, handler)
}
