def compile_multi3(context):
    """
    Compile the multi3() helper function used by LLVM
    for 128-bit multiplication on 32-bit platforms.
    """
    codegen = context.codegen()
    library = codegen.create_library("multi3")

    ir_mod = library.create_ir_module("multi3")

    i64 = ir.IntType(64)
    i128 = ir.IntType(128)
    lower_mask = ir.Constant(i64, 0xffffffff)
    _32 = ir.Constant(i64, 32)
    _64 = ir.Constant(i128, 64)

    fn_type = ir.FunctionType(i128, [i128, i128])
    fn = ir.Function(ir_mod, fn_type, name="multi3")

    a, b = fn.args
    bb = fn.append_basic_block()
    builder = ir.IRBuilder(bb)

    # This implementation mimics compiler-rt's.
    al = builder.trunc(a, i64)
    bl = builder.trunc(b, i64)
    ah = builder.trunc(builder.ashr(a, _64), i64)
    bh = builder.trunc(builder.ashr(b, _64), i64)

    # Compute {rh, rl} = al * bl   (unsigned 64-bit multiplication)
    # rl = (al & 0xffffffff) * (bl & 0xffffffff)
    rl = builder.mul(builder.and_(al, lower_mask), builder.and_(bl, lower_mask))
    # t = rl >> 32
    t = builder.lshr(rl, _32)
    # rl &= 0xffffffff
    rl = builder.and_(rl, lower_mask)
    # t += (al >> 32) * (bl & 0xffffffff)
    t = builder.add(t, builder.mul(builder.lshr(al, _32),
                                   builder.and_(bl, lower_mask)))
    # rl += t << 32
    rl = builder.add(rl, builder.shl(t, _32))
    # rh = t >> 32
    rh = builder.lshr(t, _32)
    # t = rl >> 32
    t = builder.lshr(rl, _32)
    # rl &= 0xffffffff
    rl = builder.and_(rl, lower_mask)
    # t += (bl >> 32) * (al & 0xffffffff)
    t = builder.add(t, builder.mul(builder.lshr(bl, _32),
                                   builder.and_(al, lower_mask)))
    # rl += t << 32
    rl = builder.add(rl, builder.shl(t, _32))
    # rh += t >> 32
    rh = builder.add(rh, builder.lshr(t, _32))
    # rh += (al >> 32) * (bl >> 32)
    rh = builder.add(rh, builder.mul(builder.lshr(al, _32),
                                     builder.lshr(bl, _32)))

    # rh += (bh * al) + (bl * ah)
    rh = builder.add(rh, builder.mul(bh, al))
    rh = builder.add(rh, builder.mul(bl, ah))

    # r = rl + (rh << 64)
    r = builder.zext(rl, i128)
    r = builder.add(r, builder.shl(builder.zext(rh, i128), _64))
    builder.ret(r)

    library.add_ir_module(ir_mod)
    library.finalize()

    return library

    Compile the multi3() helper function used by LLVM
    for 128-bit multiplication on 32-bit platforms.
    
numba/core/externals.py