//! Module to handle integer operations.
//! This module exists because some integer types are not supported on some gcc platforms, e.g.
//! 128-bit integers on 32-bit platforms and thus require to be handled manually.

// cSpell:words cmpti divti modti mulodi muloti udivti umodti

use gccjit::{
    BinaryOp, CType, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp,
};
use rustc_abi::{CanonAbi, Endian, ExternAbi};
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
use rustc_middle::ty::{self, Ty};
use rustc_target::callconv::{ArgAbi, ArgAttributes, FnAbi, PassMode};
use rustc_type_ir::{Interner, TyKind};

use crate::builder::{Builder, ToGccComp};
use crate::common::{SignType, TypeReflection};
use crate::context::CodegenCx;

impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
    pub fn gcc_urem(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        // 128-bit unsigned %: __umodti3
        self.multiplicative_operation(BinaryOp::Modulo, "mod", false, a, b)
    }

    pub fn gcc_srem(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        // 128-bit signed %:   __modti3
        self.multiplicative_operation(BinaryOp::Modulo, "mod", true, a, b)
    }

    pub fn gcc_not(&self, a: RValue<'gcc>) -> RValue<'gcc> {
        let typ = a.get_type();
        if self.is_native_int_type_or_bool(typ) {
            let operation =
                if typ.is_bool() { UnaryOp::LogicalNegate } else { UnaryOp::BitwiseNegate };
            self.cx.context.new_unary_op(self.location, operation, typ, a)
        } else {
            let element_type = typ.dyncast_array().expect("element type");
            self.concat_low_high_rvalues(
                typ,
                self.cx.context.new_unary_op(
                    self.location,
                    UnaryOp::BitwiseNegate,
                    element_type,
                    self.low(a),
                ),
                self.cx.context.new_unary_op(
                    self.location,
                    UnaryOp::BitwiseNegate,
                    element_type,
                    self.high(a),
                ),
            )
        }
    }

    pub fn gcc_neg(&self, a: RValue<'gcc>) -> RValue<'gcc> {
        let a_type = a.get_type();
        if self.is_native_int_type(a_type) || a_type.is_vector() {
            self.cx.context.new_unary_op(self.location, UnaryOp::Minus, a.get_type(), a)
        } else {
            self.gcc_add(self.gcc_not(a), self.gcc_int(a_type, 1))
        }
    }

    pub fn gcc_and(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        self.cx.bitwise_operation(BinaryOp::BitwiseAnd, a, b, self.location)
    }

    pub fn gcc_lshr(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        let a_type = a.get_type();
        let b_type = b.get_type();
        let a_native = self.is_native_int_type(a_type);
        let b_native = self.is_native_int_type(b_type);
        if a_native && b_native {
            // FIXME(antoyo): remove the casts when libgccjit can shift an unsigned number by a signed number.
            // TODO(antoyo): cast to unsigned to do a logical shift if that does not work.
            if a_type.is_signed(self) != b_type.is_signed(self) {
                let b = self.context.new_cast(self.location, b, a_type);
                a >> b
            } else {
                let a_size = a_type.get_size();
                let b_size = b_type.get_size();
                match a_size.cmp(&b_size) {
                    std::cmp::Ordering::Less => {
                        let a = self.context.new_cast(self.location, a, b_type);
                        a >> b
                    }
                    std::cmp::Ordering::Equal => a >> b,
                    std::cmp::Ordering::Greater => {
                        let b = self.context.new_cast(self.location, b, a_type);
                        a >> b
                    }
                }
            }
        } else if a_type.is_vector() && b_type.is_vector() {
            a >> b
        } else if a_native && !b_native {
            self.gcc_lshr(a, self.gcc_int_cast(b, a_type))
        } else {
            // NOTE: we cannot use the lshr builtin because it's calling hi() (to get the most
            // significant half of the number) which uses lshr.

            let native_int_type = a_type.dyncast_array().expect("get element type");

            let func = self.current_func();
            let then_block = func.new_block("then");
            let else_block = func.new_block("else");
            let after_block = func.new_block("after");
            let b0_block = func.new_block("b0");
            let actual_else_block = func.new_block("actual_else");

            let result = func.new_local(self.location, a_type, "shiftResult");

            let sixty_four = self.gcc_int(native_int_type, 64);
            let sixty_three = self.gcc_int(native_int_type, 63);
            let zero = self.gcc_zero(native_int_type);
            let b = self.gcc_int_cast(b, native_int_type);
            let condition = self.gcc_icmp(IntPredicate::IntNE, self.gcc_and(b, sixty_four), zero);
            self.llbb().end_with_conditional(self.location, condition, then_block, else_block);

            let shift_value = self.gcc_sub(b, sixty_four);
            let high = self.high(a);
            let sign = if a_type.is_signed(self) { high >> sixty_three } else { zero };
            let array_value = self.concat_low_high_rvalues(a_type, high >> shift_value, sign);
            then_block.add_assignment(self.location, result, array_value);
            then_block.end_with_jump(self.location, after_block);

            let condition = self.gcc_icmp(IntPredicate::IntEQ, b, zero);
            else_block.end_with_conditional(self.location, condition, b0_block, actual_else_block);

            b0_block.add_assignment(self.location, result, a);
            b0_block.end_with_jump(self.location, after_block);

            let shift_value = self.gcc_sub(sixty_four, b);
            // NOTE: cast low to its unsigned type in order to perform a logical right shift.
            let unsigned_type = native_int_type.to_unsigned(self.cx);
            let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type);
            let shifted_low = casted_low >> self.context.new_cast(self.location, b, unsigned_type);
            let shifted_low = self.context.new_cast(self.location, shifted_low, native_int_type);
            let array_value = self.concat_low_high_rvalues(
                a_type,
                (high << shift_value) | shifted_low,
                high >> b,
            );
            actual_else_block.add_assignment(self.location, result, array_value);
            actual_else_block.end_with_jump(self.location, after_block);

            // NOTE: since jumps were added in a place rustc does not expect, the current block in the
            // state need to be updated.
            self.switch_to_block(after_block);

            result.to_rvalue()
        }
    }

    fn additive_operation(
        &self,
        operation: BinaryOp,
        a: RValue<'gcc>,
        mut b: RValue<'gcc>,
    ) -> RValue<'gcc> {
        let a_type = a.get_type();
        let b_type = b.get_type();
        if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type))
            || (a_type.is_vector() && b_type.is_vector())
        {
            if a_type != b_type {
                if a_type.is_vector() {
                    // Vector types need to be bitcast.
                    // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
                    b = self.context.new_bitcast(self.location, b, a_type);
                } else {
                    b = self.context.new_cast(self.location, b, a_type);
                }
            }
            self.context.new_binary_op(self.location, operation, a_type, a, b)
        } else {
            debug_assert!(a_type.dyncast_array().is_some());
            debug_assert!(b_type.dyncast_array().is_some());
            let signed = a_type.is_compatible_with(self.i128_type);
            let func_name = match (operation, signed) {
                (BinaryOp::Plus, true) => "__rust_i128_add",
                (BinaryOp::Plus, false) => "__rust_u128_add",
                (BinaryOp::Minus, true) => "__rust_i128_sub",
                (BinaryOp::Minus, false) => "__rust_u128_sub",
                _ => unreachable!("unexpected additive operation {:?}", operation),
            };
            let param_a = self.context.new_parameter(self.location, a_type, "a");
            let param_b = self.context.new_parameter(self.location, b_type, "b");
            let func = self.context.new_function(
                self.location,
                FunctionType::Extern,
                a_type,
                &[param_a, param_b],
                func_name,
                false,
            );
            self.context.new_call(self.location, func, &[a, b])
        }
    }

    pub fn gcc_add(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        self.additive_operation(BinaryOp::Plus, a, b)
    }

    pub fn gcc_mul(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        self.multiplicative_operation(BinaryOp::Mult, "mul", true, a, b)
    }

    pub fn gcc_sub(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        self.additive_operation(BinaryOp::Minus, a, b)
    }

    fn multiplicative_operation(
        &self,
        operation: BinaryOp,
        operation_name: &str,
        signed: bool,
        a: RValue<'gcc>,
        mut b: RValue<'gcc>,
    ) -> RValue<'gcc> {
        let a_type = a.get_type();
        let b_type = b.get_type();
        if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type))
            || (a_type.is_vector() && b_type.is_vector())
        {
            if !a_type.is_compatible_with(b_type) {
                if a_type.is_vector() {
                    // Vector types need to be bitcast.
                    // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
                    b = self.context.new_bitcast(self.location, b, a_type);
                } else {
                    b = self.context.new_cast(self.location, b, a_type);
                }
            }
            self.context.new_binary_op(self.location, operation, a_type, a, b)
        } else {
            debug_assert!(a_type.dyncast_array().is_some());
            debug_assert!(b_type.dyncast_array().is_some());
            let sign = if signed { "" } else { "u" };
            let func_name = format!("__{}{}ti3", sign, operation_name);
            let param_a = self.context.new_parameter(self.location, a_type, "a");
            let param_b = self.context.new_parameter(self.location, b_type, "b");
            let func = self.context.new_function(
                self.location,
                FunctionType::Extern,
                a_type,
                &[param_a, param_b],
                func_name,
                false,
            );
            self.context.new_call(self.location, func, &[a, b])
        }
    }

    pub fn gcc_sdiv(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        // TODO(antoyo): check if the types are signed?
        // 128-bit, signed: __divti3
        // TODO(antoyo): convert the arguments to signed?
        self.multiplicative_operation(BinaryOp::Divide, "div", true, a, b)
    }

    pub fn gcc_udiv(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        // 128-bit, unsigned: __udivti3
        self.multiplicative_operation(BinaryOp::Divide, "div", false, a, b)
    }

    pub fn gcc_checked_binop(
        &self,
        oop: OverflowOp,
        typ: Ty<'_>,
        lhs: <Self as BackendTypes>::Value,
        rhs: <Self as BackendTypes>::Value,
    ) -> (<Self as BackendTypes>::Value, <Self as BackendTypes>::Value) {
        use rustc_middle::ty::IntTy::*;
        use rustc_middle::ty::UintTy::*;
        use rustc_middle::ty::{Int, Uint};

        let new_kind = match *typ.kind() {
            Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
            Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),
            t @ (Uint(_) | Int(_)) => t,
            _ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
        };

        // TODO(antoyo): remove duplication with intrinsic?
        let name = if self.is_native_int_type(lhs.get_type()) {
            match oop {
                OverflowOp::Add => match new_kind {
                    Int(I8) => "__builtin_add_overflow",
                    Int(I16) => "__builtin_add_overflow",
                    Int(I32) => "__builtin_sadd_overflow",
                    Int(I64) => "__builtin_saddll_overflow",
                    Int(I128) => "__builtin_add_overflow",

                    Uint(U8) => "__builtin_add_overflow",
                    Uint(U16) => "__builtin_add_overflow",
                    Uint(U32) => "__builtin_uadd_overflow",
                    Uint(U64) => "__builtin_uaddll_overflow",
                    Uint(U128) => "__builtin_add_overflow",

                    _ => unreachable!(),
                },
                OverflowOp::Sub => match new_kind {
                    Int(I8) => "__builtin_sub_overflow",
                    Int(I16) => "__builtin_sub_overflow",
                    Int(I32) => "__builtin_ssub_overflow",
                    Int(I64) => "__builtin_ssubll_overflow",
                    Int(I128) => "__builtin_sub_overflow",

                    Uint(U8) => "__builtin_sub_overflow",
                    Uint(U16) => "__builtin_sub_overflow",
                    Uint(U32) => "__builtin_usub_overflow",
                    Uint(U64) => "__builtin_usubll_overflow",
                    Uint(U128) => "__builtin_sub_overflow",

                    _ => unreachable!(),
                },
                OverflowOp::Mul => match new_kind {
                    Int(I8) => "__builtin_mul_overflow",
                    Int(I16) => "__builtin_mul_overflow",
                    Int(I32) => "__builtin_smul_overflow",
                    Int(I64) => "__builtin_smulll_overflow",
                    Int(I128) => "__builtin_mul_overflow",

                    Uint(U8) => "__builtin_mul_overflow",
                    Uint(U16) => "__builtin_mul_overflow",
                    Uint(U32) => "__builtin_umul_overflow",
                    Uint(U64) => "__builtin_umulll_overflow",
                    Uint(U128) => "__builtin_mul_overflow",

                    _ => unreachable!(),
                },
            }
        } else {
            let (func_name, width) = match oop {
                OverflowOp::Add => match new_kind {
                    Int(I128) => ("__rust_i128_addo", 128),
                    Uint(U128) => ("__rust_u128_addo", 128),
                    _ => unreachable!(),
                },
                OverflowOp::Sub => match new_kind {
                    Int(I128) => ("__rust_i128_subo", 128),
                    Uint(U128) => ("__rust_u128_subo", 128),
                    _ => unreachable!(),
                },
                OverflowOp::Mul => match new_kind {
                    Int(I32) => ("__mulosi4", 32),
                    Int(I64) => ("__mulodi4", 64),
                    Int(I128) => ("__rust_i128_mulo", 128), // TODO(antoyo): use __muloti4d instead?
                    Uint(U128) => ("__rust_u128_mulo", 128),
                    _ => unreachable!(),
                },
            };
            return self.operation_with_overflow(func_name, lhs, rhs, width);
        };

        let intrinsic = self.context.get_builtin_function(name);
        let res = self
            .current_func()
            // TODO(antoyo): is it correct to use rhs type instead of the parameter typ?
            .new_local(self.location, rhs.get_type(), "binopResult")
            .get_address(self.location);
        let new_type = type_kind_to_gcc_type(new_kind);
        let new_type = self.context.new_c_type(new_type);
        let lhs = self.context.new_cast(self.location, lhs, new_type);
        let rhs = self.context.new_cast(self.location, rhs, new_type);
        let res = self.context.new_cast(self.location, res, new_type.make_pointer());
        let overflow = self.overflow_call(intrinsic, &[lhs, rhs, res], None);
        (res.dereference(self.location).to_rvalue(), overflow)
    }

    /// Non-`__builtin_*` overflow operations with a `fn(T, T, &mut i32) -> T` signature.
    pub fn operation_with_overflow(
        &self,
        func_name: &str,
        lhs: RValue<'gcc>,
        rhs: RValue<'gcc>,
        width: u64,
    ) -> (RValue<'gcc>, RValue<'gcc>) {
        let a_type = lhs.get_type();
        let b_type = rhs.get_type();
        debug_assert!(a_type.dyncast_array().is_some());
        debug_assert!(b_type.dyncast_array().is_some());
        let overflow_type = self.i32_type;
        let overflow_param_type = overflow_type.make_pointer();
        let res_type = a_type;

        let overflow_value =
            self.current_func().new_local(self.location, overflow_type, "overflow");
        let overflow_addr = overflow_value.get_address(self.location);

        let param_a = self.context.new_parameter(self.location, a_type, "a");
        let param_b = self.context.new_parameter(self.location, b_type, "b");
        let param_overflow =
            self.context.new_parameter(self.location, overflow_param_type, "overflow");

        let a_elem_type = a_type.dyncast_array().expect("non-array a value");
        debug_assert!(a_elem_type.is_integral());
        let res_ty = match width {
            32 => self.tcx.types.i32,
            64 => self.tcx.types.i64,
            128 => self.tcx.types.i128,
            _ => unreachable!("unexpected integer size"),
        };
        let layout = self
            .tcx
            .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(res_ty))
            .unwrap();

        let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) };
        let mut fn_abi = FnAbi {
            args: vec![arg_abi.clone(), arg_abi.clone(), arg_abi.clone()].into_boxed_slice(),
            ret: arg_abi,
            c_variadic: false,
            fixed_count: 3,
            conv: CanonAbi::C,
            can_unwind: false,
        };
        fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false });

        let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });

        let call = if ret_indirect {
            let res_value = self.current_func().new_local(self.location, res_type, "result_value");
            let res_addr = res_value.get_address(self.location);
            let res_param_type = res_type.make_pointer();
            let param_res = self.context.new_parameter(self.location, res_param_type, "result");

            let func = self.context.new_function(
                self.location,
                FunctionType::Extern,
                self.type_void(),
                &[param_res, param_a, param_b, param_overflow],
                func_name,
                false,
            );
            let _void =
                self.context.new_call(self.location, func, &[res_addr, lhs, rhs, overflow_addr]);
            res_value.to_rvalue()
        } else {
            let func = self.context.new_function(
                self.location,
                FunctionType::Extern,
                res_type,
                &[param_a, param_b, param_overflow],
                func_name,
                false,
            );
            self.context.new_call(self.location, func, &[lhs, rhs, overflow_addr])
        };
        // NOTE: we must assign the result of the operation to a variable at this point to make
        // sure it will be evaluated by libgccjit now.
        // Otherwise, it will only be evaluated when the rvalue for the call is used somewhere else
        // and overflow_value will not be initialized at the correct point in the program.
        let result = self.current_func().new_local(self.location, res_type, "result");
        self.block.add_assignment(self.location, result, call);

        (
            result.to_rvalue(),
            self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue(),
        )
    }

    pub fn gcc_icmp(
        &mut self,
        op: IntPredicate,
        mut lhs: RValue<'gcc>,
        mut rhs: RValue<'gcc>,
    ) -> RValue<'gcc> {
        let a_type = lhs.get_type();
        let b_type = rhs.get_type();
        if self.is_non_native_int_type(a_type) || self.is_non_native_int_type(b_type) {
            // This algorithm is based on compiler-rt's __cmpti2:
            // https://github.com/llvm-mirror/compiler-rt/blob/f0745e8476f069296a7c71accedd061dce4cdf79/lib/builtins/cmpti2.c#L21
            let result = self.current_func().new_local(self.location, self.int_type, "icmp_result");
            let block1 = self.current_func().new_block("block1");
            let block2 = self.current_func().new_block("block2");
            let block3 = self.current_func().new_block("block3");
            let block4 = self.current_func().new_block("block4");
            let block5 = self.current_func().new_block("block5");
            let block6 = self.current_func().new_block("block6");
            let block7 = self.current_func().new_block("block7");
            let block8 = self.current_func().new_block("block8");
            let after = self.current_func().new_block("after");

            let native_int_type = a_type.dyncast_array().expect("get element type");
            // NOTE: cast low to its unsigned type in order to perform a comparison correctly (e.g.
            // the sign is only on high).
            let unsigned_type = native_int_type.to_unsigned(self.cx);

            let lhs_low = self.context.new_cast(self.location, self.low(lhs), unsigned_type);
            let rhs_low = self.context.new_cast(self.location, self.low(rhs), unsigned_type);

            let mut lhs_high = self.high(lhs);
            let mut rhs_high = self.high(rhs);

            match op {
                IntPredicate::IntUGT
                | IntPredicate::IntUGE
                | IntPredicate::IntULT
                | IntPredicate::IntULE => {
                    lhs_high = self.context.new_cast(self.location, lhs_high, unsigned_type);
                    rhs_high = self.context.new_cast(self.location, rhs_high, unsigned_type);
                }
                // TODO(antoyo): we probably need to handle signed comparison for unsigned
                // integers.
                _ => (),
            }

            let condition = self.context.new_comparison(
                self.location,
                ComparisonOp::LessThan,
                lhs_high,
                rhs_high,
            );
            self.llbb().end_with_conditional(self.location, condition, block1, block2);

            block1.add_assignment(
                self.location,
                result,
                self.context.new_rvalue_zero(self.int_type),
            );
            block1.end_with_jump(self.location, after);

            let condition = self.context.new_comparison(
                self.location,
                ComparisonOp::GreaterThan,
                lhs_high,
                rhs_high,
            );
            block2.end_with_conditional(self.location, condition, block3, block4);

            block3.add_assignment(
                self.location,
                result,
                self.context.new_rvalue_from_int(self.int_type, 2),
            );
            block3.end_with_jump(self.location, after);

            let condition = self.context.new_comparison(
                self.location,
                ComparisonOp::LessThan,
                lhs_low,
                rhs_low,
            );
            block4.end_with_conditional(self.location, condition, block5, block6);

            block5.add_assignment(
                self.location,
                result,
                self.context.new_rvalue_zero(self.int_type),
            );
            block5.end_with_jump(self.location, after);

            let condition = self.context.new_comparison(
                self.location,
                ComparisonOp::GreaterThan,
                lhs_low,
                rhs_low,
            );
            block6.end_with_conditional(self.location, condition, block7, block8);

            block7.add_assignment(
                self.location,
                result,
                self.context.new_rvalue_from_int(self.int_type, 2),
            );
            block7.end_with_jump(self.location, after);

            block8.add_assignment(
                self.location,
                result,
                self.context.new_rvalue_one(self.int_type),
            );
            block8.end_with_jump(self.location, after);

            // NOTE: since jumps were added in a place rustc does not expect, the current block in the
            // state need to be updated.
            self.switch_to_block(after);

            let cmp = result.to_rvalue();
            let (op, limit) = match op {
                IntPredicate::IntEQ => {
                    return self.context.new_comparison(
                        self.location,
                        ComparisonOp::Equals,
                        cmp,
                        self.context.new_rvalue_one(self.int_type),
                    );
                }
                IntPredicate::IntNE => {
                    return self.context.new_comparison(
                        self.location,
                        ComparisonOp::NotEquals,
                        cmp,
                        self.context.new_rvalue_one(self.int_type),
                    );
                }
                // TODO(antoyo): cast to u128 for unsigned comparison. See below.
                IntPredicate::IntUGT => (ComparisonOp::Equals, 2),
                IntPredicate::IntUGE => (ComparisonOp::GreaterThanEquals, 1),
                IntPredicate::IntULT => (ComparisonOp::Equals, 0),
                IntPredicate::IntULE => (ComparisonOp::LessThanEquals, 1),
                IntPredicate::IntSGT => (ComparisonOp::Equals, 2),
                IntPredicate::IntSGE => (ComparisonOp::GreaterThanEquals, 1),
                IntPredicate::IntSLT => (ComparisonOp::Equals, 0),
                IntPredicate::IntSLE => (ComparisonOp::LessThanEquals, 1),
            };
            self.context.new_comparison(
                self.location,
                op,
                cmp,
                self.context.new_rvalue_from_int(self.int_type, limit),
            )
        } else if a_type.get_pointee().is_some() && b_type.get_pointee().is_some() {
            // NOTE: gcc cannot compare pointers to different objects, but rustc does that, so cast them to usize.
            lhs = self.context.new_bitcast(self.location, lhs, self.usize_type);
            rhs = self.context.new_bitcast(self.location, rhs, self.usize_type);
            self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs)
        } else {
            if a_type != b_type {
                // NOTE: because libgccjit cannot compare function pointers.
                if a_type.dyncast_function_ptr_type().is_some()
                    && b_type.dyncast_function_ptr_type().is_some()
                {
                    lhs = self.context.new_cast(self.location, lhs, self.usize_type.make_pointer());
                    rhs = self.context.new_cast(self.location, rhs, self.usize_type.make_pointer());
                }
                // NOTE: hack because we try to cast a vector type to the same vector type.
                else if format!("{:?}", a_type) != format!("{:?}", b_type) {
                    rhs = self.context.new_cast(self.location, rhs, a_type);
                }
            }
            match op {
                IntPredicate::IntUGT
                | IntPredicate::IntUGE
                | IntPredicate::IntULT
                | IntPredicate::IntULE => {
                    if !a_type.is_vector() {
                        let unsigned_type = a_type.to_unsigned(self.cx);
                        lhs = self.context.new_cast(self.location, lhs, unsigned_type);
                        rhs = self.context.new_cast(self.location, rhs, unsigned_type);
                    }
                }
                // TODO(antoyo): we probably need to handle signed comparison for unsigned
                // integers.
                _ => (),
            }
            self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs)
        }
    }

    pub fn gcc_xor(&self, a: RValue<'gcc>, mut b: RValue<'gcc>) -> RValue<'gcc> {
        let a_type = a.get_type();
        let b_type = b.get_type();
        if a_type.is_vector() && b_type.is_vector() {
            let b = self.bitcast_if_needed(b, a_type);
            a ^ b
        } else if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)
        {
            if !a_type.is_compatible_with(b_type) {
                b = self.context.new_cast(self.location, b, a_type);
            }
            a ^ b
        } else {
            self.concat_low_high_rvalues(
                a_type,
                self.low(a) ^ self.low(b),
                self.high(a) ^ self.high(b),
            )
        }
    }

    pub fn gcc_shl(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
        let a_type = a.get_type();
        let b_type = b.get_type();
        let a_native = self.is_native_int_type(a_type);
        let b_native = self.is_native_int_type(b_type);
        if a_native && b_native {
            // FIXME(antoyo): remove the casts when libgccjit can shift an unsigned number by an unsigned number.
            if a_type.is_unsigned(self) && b_type.is_signed(self) {
                let a = self.context.new_cast(self.location, a, b_type);
                let result = a << b;
                self.context.new_cast(self.location, result, a_type)
            } else if a_type.is_signed(self) && b_type.is_unsigned(self) {
                let b = self.context.new_cast(self.location, b, a_type);
                a << b
            } else {
                let a_size = a_type.get_size();
                let b_size = b_type.get_size();
                match a_size.cmp(&b_size) {
                    std::cmp::Ordering::Less => {
                        let a = self.context.new_cast(self.location, a, b_type);
                        a << b
                    }
                    std::cmp::Ordering::Equal => a << b,
                    std::cmp::Ordering::Greater => {
                        let b = self.context.new_cast(self.location, b, a_type);
                        a << b
                    }
                }
            }
        } else if a_type.is_vector() && b_type.is_vector() {
            a << b
        } else if a_native && !b_native {
            self.gcc_shl(a, self.gcc_int_cast(b, a_type))
        } else {
            // NOTE: we cannot use the ashl builtin because it's calling widen_hi() which uses ashl.
            let native_int_type = a_type.dyncast_array().expect("get element type");

            let func = self.current_func();
            let then_block = func.new_block("then");
            let else_block = func.new_block("else");
            let after_block = func.new_block("after");
            let b0_block = func.new_block("b0");
            let actual_else_block = func.new_block("actual_else");

            let result = func.new_local(self.location, a_type, "shiftResult");

            let b = self.gcc_int_cast(b, native_int_type);
            let sixty_four = self.gcc_int(native_int_type, 64);
            let zero = self.gcc_zero(native_int_type);
            let condition = self.gcc_icmp(IntPredicate::IntNE, self.gcc_and(b, sixty_four), zero);
            self.llbb().end_with_conditional(self.location, condition, then_block, else_block);

            let array_value =
                self.concat_low_high_rvalues(a_type, zero, self.low(a) << (b - sixty_four));
            then_block.add_assignment(self.location, result, array_value);
            then_block.end_with_jump(self.location, after_block);

            let condition = self.gcc_icmp(IntPredicate::IntEQ, b, zero);
            else_block.end_with_conditional(self.location, condition, b0_block, actual_else_block);

            b0_block.add_assignment(self.location, result, a);
            b0_block.end_with_jump(self.location, after_block);

            // NOTE: cast low to its unsigned type in order to perform a logical right shift.
            // TODO(antoyo): adjust this ^ comment.
            let unsigned_type = native_int_type.to_unsigned(self.cx);
            let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type);
            let shift_value = self.context.new_cast(self.location, sixty_four - b, unsigned_type);
            let high_low =
                self.context.new_cast(self.location, casted_low >> shift_value, native_int_type);

            let array_value = self.concat_low_high_rvalues(
                a_type,
                self.low(a) << b,
                (self.high(a) << b) | high_low,
            );
            actual_else_block.add_assignment(self.location, result, array_value);
            actual_else_block.end_with_jump(self.location, after_block);

            // NOTE: since jumps were added in a place rustc does not expect, the current block in the
            // state need to be updated.
            self.switch_to_block(after_block);

            result.to_rvalue()
        }
    }

    pub fn gcc_bswap(&mut self, mut arg: RValue<'gcc>, width: u64) -> RValue<'gcc> {
        let arg_type = arg.get_type();
        if !self.is_native_int_type(arg_type) {
            let native_int_type = arg_type.dyncast_array().expect("get element type");
            let lsb = self.low(arg);
            let swapped_lsb = self.gcc_bswap(lsb, width / 2);
            let swapped_lsb = self.context.new_cast(self.location, swapped_lsb, native_int_type);
            let msb = self.high(arg);
            let swapped_msb = self.gcc_bswap(msb, width / 2);
            let swapped_msb = self.context.new_cast(self.location, swapped_msb, native_int_type);

            // NOTE: we also need to swap the two elements here, in addition to swapping inside
            // the elements themselves like done above.
            return self.concat_low_high_rvalues(arg_type, swapped_msb, swapped_lsb);
        }

        // TODO(antoyo): check if it's faster to use string literals and a
        // match instead of format!.
        let bswap = self.cx.context.get_builtin_function(format!("__builtin_bswap{}", width));
        // FIXME(antoyo): this cast should not be necessary. Remove
        // when having proper sized integer types.
        let param_type = bswap.get_param(0).to_rvalue().get_type();
        if param_type != arg_type {
            arg = self.bitcast(arg, param_type);
        }
        self.cx.context.new_call(self.location, bswap, &[arg])
    }
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
    pub fn gcc_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
        if self.is_native_int_type_or_bool(typ) {
            self.context.new_rvalue_from_long(typ, int)
        } else {
            // NOTE: set the sign in high.
            self.concat_low_high(typ, int, -(int.is_negative() as i64))
        }
    }

    pub fn gcc_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
        if typ.is_u128(self) {
            // FIXME(antoyo): libgccjit cannot create 128-bit values yet.
            let num = self.context.new_rvalue_from_long(self.u64_type, int as i64);
            self.gcc_int_cast(num, typ)
        } else if self.is_native_int_type_or_bool(typ) {
            self.context.new_rvalue_from_long(typ, int as i64)
        } else {
            self.concat_low_high(typ, int as i64, 0)
        }
    }

    pub fn gcc_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
        let low = num as u64;
        let high = (num >> 64) as u64;
        if num >> 64 != 0 {
            // FIXME(antoyo): use a new function new_rvalue_from_unsigned_long()?
            if self.is_native_int_type(typ) {
                let low = self.context.new_rvalue_from_long(self.u64_type, low as i64);
                let high = self.context.new_rvalue_from_long(typ, high as i64);

                let sixty_four = self.context.new_rvalue_from_long(typ, 64);
                let shift = high << sixty_four;
                shift | self.context.new_cast(None, low, typ)
            } else {
                self.concat_low_high(typ, low as i64, high as i64)
            }
        } else if typ.is_i128(self) {
            // FIXME(antoyo): libgccjit cannot create 128-bit values yet.
            let num = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64);
            self.gcc_int_cast(num, typ)
        } else {
            self.gcc_uint(typ, num as u64)
        }
    }

    pub fn gcc_zero(&self, typ: Type<'gcc>) -> RValue<'gcc> {
        if self.is_native_int_type_or_bool(typ) {
            self.context.new_rvalue_zero(typ)
        } else {
            self.concat_low_high(typ, 0, 0)
        }
    }

    pub fn gcc_int_width(&self, typ: Type<'gcc>) -> u64 {
        if self.is_native_int_type_or_bool(typ) {
            typ.get_size() as u64 * 8
        } else {
            // NOTE: the only unsupported types are u128 and i128.
            128
        }
    }

    fn bitwise_operation(
        &self,
        operation: BinaryOp,
        a: RValue<'gcc>,
        mut b: RValue<'gcc>,
        loc: Option<Location<'gcc>>,
    ) -> RValue<'gcc> {
        let a_type = a.get_type();
        let b_type = b.get_type();
        let a_native = self.is_native_int_type_or_bool(a_type);
        let b_native = self.is_native_int_type_or_bool(b_type);
        if a_type.is_vector() && b_type.is_vector() {
            let b = self.bitcast_if_needed(b, a_type);
            self.context.new_binary_op(loc, operation, a_type, a, b)
        } else if a_native && b_native {
            if a_type != b_type {
                b = self.context.new_cast(loc, b, a_type);
            }
            self.context.new_binary_op(loc, operation, a_type, a, b)
        } else {
            assert!(
                !a_native && !b_native,
                "both types should either be native or non-native for or operation"
            );
            let native_int_type = a_type.dyncast_array().expect("get element type");
            self.concat_low_high_rvalues(
                a_type,
                self.context.new_binary_op(
                    loc,
                    operation,
                    native_int_type,
                    self.low(a),
                    self.low(b),
                ),
                self.context.new_binary_op(
                    loc,
                    operation,
                    native_int_type,
                    self.high(a),
                    self.high(b),
                ),
            )
        }
    }

    pub fn gcc_or(
        &self,
        a: RValue<'gcc>,
        b: RValue<'gcc>,
        loc: Option<Location<'gcc>>,
    ) -> RValue<'gcc> {
        self.bitwise_operation(BinaryOp::BitwiseOr, a, b, loc)
    }

    // TODO(antoyo): can we use https://github.com/rust-lang/compiler-builtins/blob/master/src/int/mod.rs#L379 instead?
    pub fn gcc_int_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
        let value_type = value.get_type();
        if self.is_native_int_type_or_bool(dest_typ) && self.is_native_int_type_or_bool(value_type)
        {
            // TODO: use self.location.
            self.context.new_cast(None, value, dest_typ)
        } else if self.is_native_int_type_or_bool(dest_typ) {
            self.context.new_cast(None, self.low(value), dest_typ)
        } else if self.is_native_int_type_or_bool(value_type) {
            let dest_element_type = dest_typ.dyncast_array().expect("get element type");

            // NOTE: set the sign of the value.
            let zero = self.context.new_rvalue_zero(value_type);
            let is_negative =
                self.context.new_comparison(None, ComparisonOp::LessThan, value, zero);
            let is_negative = self.gcc_int_cast(is_negative, dest_element_type);
            self.concat_low_high_rvalues(
                dest_typ,
                self.context.new_cast(None, value, dest_element_type),
                self.context.new_unary_op(None, UnaryOp::Minus, dest_element_type, is_negative),
            )
        } else {
            // Since u128 and i128 are the only types that can be unsupported, we know the type of
            // value and the destination type have the same size, so a bitcast is fine.

            // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
            self.context.new_bitcast(None, value, dest_typ)
        }
    }

    fn int_to_float_cast(
        &self,
        signed: bool,
        value: RValue<'gcc>,
        dest_typ: Type<'gcc>,
    ) -> RValue<'gcc> {
        let value_type = value.get_type();
        if self.is_native_int_type_or_bool(value_type) {
            return self.context.new_cast(None, value, dest_typ);
        }

        debug_assert!(value_type.dyncast_array().is_some());
        let name_suffix = match self.type_kind(dest_typ) {
            // cSpell:disable
            TypeKind::Float => "tisf",
            TypeKind::Double => "tidf",
            TypeKind::FP128 => "titf",
            // cSpell:enable
            kind => panic!("cannot cast a non-native integer to type {:?}", kind),
        };
        let sign = if signed { "" } else { "un" };
        let func_name = format!("__float{}{}", sign, name_suffix);
        let param = self.context.new_parameter(None, value_type, "n");
        let func = self.context.new_function(
            None,
            FunctionType::Extern,
            dest_typ,
            &[param],
            func_name,
            false,
        );
        self.context.new_call(None, func, &[value])
    }

    pub fn gcc_int_to_float_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
        self.int_to_float_cast(true, value, dest_typ)
    }

    pub fn gcc_uint_to_float_cast(
        &self,
        value: RValue<'gcc>,
        dest_typ: Type<'gcc>,
    ) -> RValue<'gcc> {
        self.int_to_float_cast(false, value, dest_typ)
    }

    fn float_to_int_cast(
        &self,
        signed: bool,
        value: RValue<'gcc>,
        dest_typ: Type<'gcc>,
    ) -> RValue<'gcc> {
        let value_type = value.get_type();
        if self.is_native_int_type_or_bool(dest_typ) {
            return self.context.new_cast(None, value, dest_typ);
        }

        debug_assert!(dest_typ.dyncast_array().is_some());
        let name_suffix = match self.type_kind(value_type) {
            // cSpell:disable
            TypeKind::Float => "sfti",
            TypeKind::Double => "dfti",
            // cSpell:enable
            kind => panic!("cannot cast a {:?} to non-native integer", kind),
        };
        let sign = if signed { "" } else { "uns" };
        let func_name = format!("__fix{}{}", sign, name_suffix);
        let param = self.context.new_parameter(None, value_type, "n");
        let func = self.context.new_function(
            None,
            FunctionType::Extern,
            dest_typ,
            &[param],
            func_name,
            false,
        );
        self.context.new_call(None, func, &[value])
    }

    pub fn gcc_float_to_int_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
        self.float_to_int_cast(true, value, dest_typ)
    }

    pub fn gcc_float_to_uint_cast(
        &self,
        value: RValue<'gcc>,
        dest_typ: Type<'gcc>,
    ) -> RValue<'gcc> {
        self.float_to_int_cast(false, value, dest_typ)
    }

    fn high(&self, value: RValue<'gcc>) -> RValue<'gcc> {
        let index = match self.sess().target.options.endian {
            Endian::Little => 1,
            Endian::Big => 0,
        };
        self.context
            .new_array_access(None, value, self.context.new_rvalue_from_int(self.int_type, index))
            .to_rvalue()
    }

    fn low(&self, value: RValue<'gcc>) -> RValue<'gcc> {
        let index = match self.sess().target.options.endian {
            Endian::Little => 0,
            Endian::Big => 1,
        };
        self.context
            .new_array_access(None, value, self.context.new_rvalue_from_int(self.int_type, index))
            .to_rvalue()
    }

    fn concat_low_high_rvalues(
        &self,
        typ: Type<'gcc>,
        low: RValue<'gcc>,
        high: RValue<'gcc>,
    ) -> RValue<'gcc> {
        let (first, last) = match self.sess().target.options.endian {
            Endian::Little => (low, high),
            Endian::Big => (high, low),
        };

        let values = [first, last];
        self.context.new_array_constructor(None, typ, &values)
    }

    fn concat_low_high(&self, typ: Type<'gcc>, low: i64, high: i64) -> RValue<'gcc> {
        let (first, last) = match self.sess().target.options.endian {
            Endian::Little => (low, high),
            Endian::Big => (high, low),
        };

        let native_int_type = typ.dyncast_array().expect("get element type");
        let values = [
            self.context.new_rvalue_from_long(native_int_type, first),
            self.context.new_rvalue_from_long(native_int_type, last),
        ];
        self.context.new_array_constructor(None, typ, &values)
    }
}

fn type_kind_to_gcc_type<I: Interner>(kind: TyKind<I>) -> CType {
    use rustc_middle::ty::IntTy::*;
    use rustc_middle::ty::UintTy::*;
    use rustc_middle::ty::{Int, Uint};

    match kind {
        Int(I8) => CType::Int8t,
        Int(I16) => CType::Int16t,
        Int(I32) => CType::Int32t,
        Int(I64) => CType::Int64t,
        Int(I128) => CType::Int128t,

        Uint(U8) => CType::UInt8t,
        Uint(U16) => CType::UInt16t,
        Uint(U32) => CType::UInt32t,
        Uint(U64) => CType::UInt64t,
        Uint(U128) => CType::UInt128t,

        _ => unimplemented!("Kind: {:?}", kind),
    }
}
