//! 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::Equal => a >> b,
                    _ => {
                        // NOTE: it is OK to cast even if b has a type bigger than a because b has
                        // been masked by codegen_ssa before calling Builder::lshr or
                        // Builder::ashr.
                        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::Equal => a << b,
                    _ => {
                        // NOTE: it is OK to cast even if b has a type bigger than a because b has
                        // been masked by codegen_ssa before calling Builder::shl.
                        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),
    }
}
