Skip to main content

src/packkit@internal@bcj.erl

-module(packkit@internal@bcj).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/packkit/internal/bcj.gleam").
-export([arm64_decode/2, arm_decode/2, ia64_decode/2, riscv_decode/2, sparc_decode/2, armthumb_decode/2, powerpc_decode/2, x86_decode/2]).
-export_type([x86_state/0, arm64_kind/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(false).

-type x86_state() :: {x86_state, integer(), integer()}.

-type arm64_kind() :: arm64_bl | arm64_adrp | arm64_other.

-file("src/packkit/internal/bcj.gleam", 171).
?DOC(false).
-spec test_msb(integer()) -> boolean().
test_msb(Byte) ->
    (Byte =:= 0) orelse (Byte =:= 16#FF).

-file("src/packkit/internal/bcj.gleam", 166).
?DOC(false).
-spec is_decodable(integer(), integer()) -> boolean().
is_decodable(Byte, Prev_mask) ->
    Mask_top = erlang:'bsr'(Prev_mask, 1),
    (test_msb(Byte) andalso (Mask_top =< 4)) andalso (Mask_top /= 3).

-file("src/packkit/internal/bcj.gleam", 175).
?DOC(false).
-spec shift_mask_left(integer(), integer()) -> integer().
shift_mask_left(Mask, By) ->
    case By of
        0 ->
            Mask;

        _ ->
            shift_mask_left(erlang:'bsl'(erlang:'band'(Mask, 16#77), 1), By - 1)
    end.

-file("src/packkit/internal/bcj.gleam", 219).
?DOC(false).
-spec mask_to_bit_number(integer()) -> integer().
mask_to_bit_number(Value) ->
    case Value of
        0 ->
            0;

        1 ->
            1;

        2 ->
            2;

        3 ->
            2;

        _ ->
            3
    end.

-file("src/packkit/internal/bcj.gleam", 285).
?DOC(false).
-spec is_powerpc_branch_link(integer(), integer()) -> boolean().
is_powerpc_branch_link(B0, B3) ->
    (erlang:'bsr'(B0, 2) =:= 16#12) andalso (erlang:'band'(B3, 3) =:= 1).

-file("src/packkit/internal/bcj.gleam", 389).
?DOC(false).
-spec is_armthumb_bl(integer(), integer()) -> boolean().
is_armthumb_bl(B1, B3) ->
    (erlang:'band'(B1, 16#F8) =:= 16#F0) andalso (erlang:'band'(B3, 16#F8) =:= 16#F8).

-file("src/packkit/internal/bcj.gleam", 490).
?DOC(false).
-spec is_sparc_call(integer(), integer()) -> boolean().
is_sparc_call(B0, B1) ->
    ((B0 =:= 16#40) andalso (erlang:'band'(B1, 16#C0) =:= 16#00)) orelse ((B0
    =:= 16#7F)
    andalso (erlang:'band'(B1, 16#C0) =:= 16#C0)).

-file("src/packkit/internal/bcj.gleam", 646).
?DOC(false).
-spec classify_arm64_instr(integer()) -> arm64_kind().
classify_arm64_instr(Instr) ->
    case erlang:'bsr'(Instr, 26) of
        16#25 ->
            arm64_bl;

        _ ->
            case erlang:'band'(Instr, 16#9F000000) =:= 16#90000000 of
                true ->
                    arm64_adrp;

                false ->
                    arm64_other
            end
    end.

-file("src/packkit/internal/bcj.gleam", 783).
?DOC(false).
-spec bit_array_to_byte_list(bitstring(), list(integer())) -> list(integer()).
bit_array_to_byte_list(Bytes, Acc) ->
    case Bytes of
        <<B, Rest/binary>> ->
            bit_array_to_byte_list(Rest, [B | Acc]);

        _ ->
            lists:reverse(Acc)
    end.

-file("src/packkit/internal/bcj.gleam", 790).
?DOC(false).
-spec byte_list_to_bit_array(list(integer()), bitstring()) -> bitstring().
byte_list_to_bit_array(Bytes, Acc) ->
    case Bytes of
        [] ->
            Acc;

        [B | Rest] ->
            byte_list_to_bit_array(Rest, <<Acc/bitstring, B>>)
    end.

-file("src/packkit/internal/bcj.gleam", 868).
?DOC(false).
-spec ia64_branch_mask(integer()) -> integer().
ia64_branch_mask(Template) ->
    case Template of
        16 ->
            4;

        17 ->
            4;

        24 ->
            4;

        25 ->
            4;

        28 ->
            4;

        29 ->
            4;

        18 ->
            6;

        19 ->
            6;

        22 ->
            7;

        23 ->
            7;

        _ ->
            0
    end.

-file("src/packkit/internal/bcj.gleam", 931).
?DOC(false).
-spec ia64_rewrite_inst_norm(integer(), integer()) -> integer().
ia64_rewrite_inst_norm(Inst_norm, Dest) ->
    Clear_lo20 = erlang:'bsl'(16#FFFFF, 13),
    Clear_bit36 = erlang:'bsl'(1, 36),
    Clear_mask = erlang:'bnot'(erlang:'bor'(Clear_lo20, Clear_bit36)),
    Cleared = erlang:'band'(Inst_norm, Clear_mask),
    Dest_lo20 = erlang:'bsl'(erlang:'band'(Dest, 16#FFFFF), 13),
    Dest_bit20 = erlang:'bsl'(erlang:'band'(Dest, 16#100000), 16),
    erlang:'bor'(Cleared, erlang:'bor'(Dest_lo20, Dest_bit20)).

-file("src/packkit/internal/bcj.gleam", 943).
?DOC(false).
-spec ia64_read_le48(list(integer()), integer(), integer()) -> integer().
ia64_read_le48(Bytes, Index, Acc) ->
    case Bytes of
        [] ->
            Acc;

        [B | Rest] ->
            Next = Acc + erlang:'bsl'(B, 8 * Index),
            ia64_read_le48(Rest, Index + 1, Next)
    end.

-file("src/packkit/internal/bcj.gleam", 953).
?DOC(false).
-spec ia64_write_le48(integer(), integer(), list(integer())) -> list(integer()).
ia64_write_le48(Value, Remaining, Acc) ->
    case Remaining of
        0 ->
            lists:reverse(Acc);

        _ ->
            Byte = erlang:'band'(Value, 16#FF),
            ia64_write_le48(erlang:'bsr'(Value, 8), Remaining - 1, [Byte | Acc])
    end.

-file("src/packkit/internal/bcj.gleam", 977).
?DOC(false).
-spec list_take_n(list(integer()), integer(), list(integer())) -> list(integer()).
list_take_n(Items, Count, Acc) ->
    case {Count, Items} of
        {0, _} ->
            lists:reverse(Acc);

        {_, []} ->
            lists:reverse(Acc);

        {_, [B | Rest]} ->
            list_take_n(Rest, Count - 1, [B | Acc])
    end.

-file("src/packkit/internal/bcj.gleam", 966).
?DOC(false).
-spec list_take_range(list(integer()), integer(), integer()) -> list(integer()).
list_take_range(Items, Start, Count) ->
    case Start of
        0 ->
            list_take_n(Items, Count, []);

        _ ->
            case Items of
                [] ->
                    [];

                [_ | Rest] ->
                    list_take_range(Rest, Start - 1, Count)
            end
    end.

-file("src/packkit/internal/bcj.gleam", 1003).
?DOC(false).
-spec list_replace_head(list(integer()), list(integer())) -> list(integer()).
list_replace_head(Items, Replacement) ->
    case Replacement of
        [] ->
            Items;

        [R | Rest_rep] ->
            case Items of
                [] ->
                    [];

                [_ | Rest] ->
                    [R | list_replace_head(Rest, Rest_rep)]
            end
    end.

-file("src/packkit/internal/bcj.gleam", 985).
?DOC(false).
-spec list_replace_range(list(integer()), integer(), list(integer())) -> list(integer()).
list_replace_range(Items, Start, Replacement) ->
    case Start of
        0 ->
            list_replace_head(Items, Replacement);

        _ ->
            case Items of
                [] ->
                    [];

                [Head | Rest] ->
                    [Head | list_replace_range(Rest, Start - 1, Replacement)]
            end
    end.

-file("src/packkit/internal/bcj.gleam", 195).
?DOC(false).
-spec x86_resolve_dest_loop(integer(), integer(), integer(), integer()) -> integer().
x86_resolve_dest_loop(_, Subtract, Prev_mask, Dest) ->
    Bit_number = mask_to_bit_number(erlang:'bsr'(Prev_mask, 1)),
    Probe_byte = erlang:'band'(erlang:'bsr'(Dest, 24 - (Bit_number * 8)), 16#FF),
    case test_msb(Probe_byte) of
        false ->
            Dest;

        true ->
            Xor_mask = case Bit_number of
                0 ->
                    16#FFFFFFFF;

                N ->
                    erlang:'band'(
                        erlang:'bsl'(1, 32 - (N * 8)) - 1,
                        16#FFFFFFFF
                    )
            end,
            New_src = erlang:'bxor'(Dest, Xor_mask),
            erlang:'band'((New_src - Subtract) + 16#100000000, 16#FFFFFFFF)
    end.

-file("src/packkit/internal/bcj.gleam", 187).
?DOC(false).
-spec x86_resolve_dest(integer(), integer(), integer()) -> integer().
x86_resolve_dest(Src, Subtract, Prev_mask) ->
    Dest = erlang:'band'((Src - Subtract) + 16#100000000, 16#FFFFFFFF),
    case Prev_mask of
        0 ->
            Dest;

        _ ->
            x86_resolve_dest_loop(Src, Subtract, Prev_mask, Dest)
    end.

-file("src/packkit/internal/bcj.gleam", 657).
?DOC(false).
-spec arm64_bl_decode(integer(), integer()) -> integer().
arm64_bl_decode(Instr, Pc) ->
    Pc_words = erlang:'bsr'(Pc, 2),
    Neg_pc = erlang:'band'(16#100000000 - Pc_words, 16#FFFFFFFF),
    _pipe = erlang:'bor'(
        16#94000000,
        erlang:'band'(Instr + Neg_pc, 16#03FFFFFF)
    ),
    erlang:'band'(_pipe, 16#FFFFFFFF).

-file("src/packkit/internal/bcj.gleam", 680).
?DOC(false).
-spec arm64_adrp_apply(integer(), integer(), integer()) -> integer().
arm64_adrp_apply(Instr, Src, Pc) ->
    Pc_pages = erlang:'bsr'(Pc, 12),
    Neg_pc = erlang:'band'(16#100000000 - Pc_pages, 16#FFFFFFFF),
    Dest = erlang:'band'(Src + Neg_pc, 16#FFFFFFFF),
    Base = erlang:'band'(Instr, 16#9000001F),
    High_immlo = erlang:'bsl'(erlang:'band'(Dest, 3), 29),
    Mid_immhi = erlang:'bsl'(erlang:'band'(Dest, 16#0003FFFC), 3),
    Sign_replica = erlang:'band'(
        16#100000000 - erlang:'band'(Dest, 16#00020000),
        16#00E00000
    ),
    _pipe = erlang:'bor'(
        erlang:'bor'(Base, High_immlo),
        erlang:'bor'(Mid_immhi, Sign_replica)
    ),
    erlang:'band'(_pipe, 16#FFFFFFFF).

-file("src/packkit/internal/bcj.gleam", 665).
?DOC(false).
-spec arm64_adrp_decode(integer(), integer()) -> {ok, integer()} | {error, nil}.
arm64_adrp_decode(Instr, Pc) ->
    Src = erlang:'bor'(
        erlang:'band'(erlang:'bsr'(Instr, 29), 3),
        erlang:'band'(erlang:'bsr'(Instr, 3), 16#001FFFFC)
    ),
    case erlang:'band'(Src + 16#00020000, 16#001C0000) of
        0 ->
            {ok, arm64_adrp_apply(Instr, Src, Pc)};

        _ ->
            {error, nil}
    end.

-file("src/packkit/internal/bcj.gleam", 699).
?DOC(false).
-spec write_le32(integer()) -> bitstring().
write_le32(Value) ->
    Masked = erlang:'band'(Value, 16#FFFFFFFF),
    <<(erlang:'band'(Masked, 16#FF)),
        (erlang:'band'(erlang:'bsr'(Masked, 8), 16#FF)),
        (erlang:'band'(erlang:'bsr'(Masked, 16), 16#FF)),
        (erlang:'band'(erlang:'bsr'(Masked, 24), 16#FF))>>.

-file("src/packkit/internal/bcj.gleam", 583).
?DOC(false).
-spec arm64_decode_words(bitstring(), integer(), integer(), bitstring()) -> bitstring().
arm64_decode_words(Bytes, Start_offset, Word_index, Acc) ->
    case Bytes of
        <<B0, B1, B2, B3, Rest/binary>> ->
            Instr = erlang:'bor'(
                erlang:'bor'(erlang:'bsl'(B3, 24), erlang:'bsl'(B2, 16)),
                erlang:'bor'(erlang:'bsl'(B1, 8), B0)
            ),
            Pc = Start_offset + (Word_index * 4),
            case classify_arm64_instr(Instr) of
                arm64_bl ->
                    New_instr = arm64_bl_decode(Instr, Pc),
                    arm64_decode_words(
                        Rest,
                        Start_offset,
                        Word_index + 1,
                        gleam_stdlib:bit_array_concat(
                            [Acc, write_le32(New_instr)]
                        )
                    );

                arm64_adrp ->
                    case arm64_adrp_decode(Instr, Pc) of
                        {ok, New_instr@1} ->
                            arm64_decode_words(
                                Rest,
                                Start_offset,
                                Word_index + 1,
                                gleam_stdlib:bit_array_concat(
                                    [Acc, write_le32(New_instr@1)]
                                )
                            );

                        {error, nil} ->
                            arm64_decode_words(
                                Rest,
                                Start_offset,
                                Word_index + 1,
                                gleam_stdlib:bit_array_concat(
                                    [Acc, <<B0, B1, B2, B3>>]
                                )
                            )
                    end;

                arm64_other ->
                    arm64_decode_words(
                        Rest,
                        Start_offset,
                        Word_index + 1,
                        gleam_stdlib:bit_array_concat([Acc, <<B0, B1, B2, B3>>])
                    )
            end;

        _ ->
            Acc
    end.

-file("src/packkit/internal/bcj.gleam", 561).
?DOC(false).
-spec arm64_decode(bitstring(), integer()) -> bitstring().
arm64_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    Aligned = Total - (Total rem 4),
    case Aligned of
        0 ->
            Bytes;

        _ ->
            case {gleam_stdlib:bit_array_slice(Bytes, 0, Aligned),
                gleam_stdlib:bit_array_slice(Bytes, Aligned, Total - Aligned)} of
                {{ok, Head}, {ok, Tail}} ->
                    Body = arm64_decode_words(Head, Start_offset, 0, <<>>),
                    gleam_stdlib:bit_array_concat([Body, Tail]);

                {_, _} ->
                    Bytes
            end
    end.

-file("src/packkit/internal/bcj.gleam", 736).
?DOC(false).
-spec arm_decode_words(bitstring(), integer(), integer(), bitstring()) -> bitstring().
arm_decode_words(Bytes, Start_offset, Word_index, Acc) ->
    case Bytes of
        <<B0, B1, B2, 16#EB, Rest/binary>> ->
            Src = erlang:'bor'(
                erlang:'bor'(erlang:'bsl'(B2, 16), erlang:'bsl'(B1, 8)),
                B0
            ),
            Src_words = erlang:'bsl'(Src, 2),
            Abs_byte_target = erlang:'band'(Src_words, 16#FFFFFFFF),
            New_target_bytes = erlang:'band'(
                (Abs_byte_target - ((Start_offset + (Word_index * 4)) + 8)) + 16#100000000,
                16#FFFFFFFF
            ),
            New_src = erlang:'bsr'(New_target_bytes, 2),
            New_b0 = erlang:'band'(New_src, 16#FF),
            New_b1 = erlang:'band'(erlang:'bsr'(New_src, 8), 16#FF),
            New_b2 = erlang:'band'(erlang:'bsr'(New_src, 16), 16#FF),
            arm_decode_words(
                Rest,
                Start_offset,
                Word_index + 1,
                gleam_stdlib:bit_array_concat(
                    [Acc, <<New_b0, New_b1, New_b2, 16#EB>>]
                )
            );

        <<B0@1, B1@1, B2@1, B3, Rest@1/binary>> ->
            arm_decode_words(
                Rest@1,
                Start_offset,
                Word_index + 1,
                gleam_stdlib:bit_array_concat([Acc, <<B0@1, B1@1, B2@1, B3>>])
            );

        _ ->
            Acc
    end.

-file("src/packkit/internal/bcj.gleam", 714).
?DOC(false).
-spec arm_decode(bitstring(), integer()) -> bitstring().
arm_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    Aligned = Total - (Total rem 4),
    case Aligned of
        0 ->
            Bytes;

        _ ->
            case {gleam_stdlib:bit_array_slice(Bytes, 0, Aligned),
                gleam_stdlib:bit_array_slice(Bytes, Aligned, Total - Aligned)} of
                {{ok, Head}, {ok, Tail}} ->
                    Body = arm_decode_words(Head, Start_offset, 0, <<>>),
                    gleam_stdlib:bit_array_concat([Body, Tail]);

                {_, _} ->
                    Bytes
            end
    end.

-file("src/packkit/internal/bcj.gleam", 893).
?DOC(false).
-spec ia64_process_slot(list(integer()), integer(), integer()) -> list(integer()).
ia64_process_slot(Bytes_list, Bit_pos, Now_pos) ->
    Byte_pos = erlang:'bsr'(Bit_pos, 3),
    Bit_res = erlang:'band'(Bit_pos, 7),
    Six = list_take_range(Bytes_list, Byte_pos, 6),
    case erlang:length(Six) =:= 6 of
        false ->
            Bytes_list;

        true ->
            Instruction = ia64_read_le48(Six, 0, 0),
            Inst_norm = erlang:'bsr'(Instruction, Bit_res),
            Major = erlang:'band'(erlang:'bsr'(Inst_norm, 37), 16#F),
            Middle = erlang:'band'(erlang:'bsr'(Inst_norm, 9), 16#7),
            case (Major =:= 16#5) andalso (Middle =:= 0) of
                false ->
                    Bytes_list;

                true ->
                    Src_lo = erlang:'band'(
                        erlang:'bsr'(Inst_norm, 13),
                        16#FFFFF
                    ),
                    Src_hi_bit = erlang:'band'(erlang:'bsr'(Inst_norm, 36), 1),
                    Src = erlang:'bsl'(Src_lo + (Src_hi_bit * 16#100000), 4),
                    Dest_byte = erlang:'band'(
                        (Src - Now_pos) + 16#100000000,
                        16#FFFFFFFF
                    ),
                    Dest = erlang:'bsr'(Dest_byte, 4),
                    New_inst_norm = ia64_rewrite_inst_norm(Inst_norm, Dest),
                    Low_mask = erlang:'bsl'(1, Bit_res) - 1,
                    Preserved = erlang:'band'(Instruction, Low_mask),
                    New_instruction = Preserved + erlang:'bsl'(
                        New_inst_norm,
                        Bit_res
                    ),
                    New_six = ia64_write_le48(New_instruction, 6, []),
                    list_replace_range(Bytes_list, Byte_pos, New_six)
            end
    end.

-file("src/packkit/internal/bcj.gleam", 877).
?DOC(false).
-spec ia64_process_slots(
    list(integer()),
    integer(),
    integer(),
    integer(),
    integer()
) -> list(integer()).
ia64_process_slots(Bytes_list, Mask, Slot, Bit_pos, Now_pos) ->
    gleam@bool:guard(
        Slot >= 3,
        Bytes_list,
        fun() ->
            Slot_active = erlang:'band'(erlang:'bsr'(Mask, Slot), 1) =:= 1,
            Updated = case Slot_active of
                true ->
                    ia64_process_slot(Bytes_list, Bit_pos, Now_pos);

                false ->
                    Bytes_list
            end,
            ia64_process_slots(Updated, Mask, Slot + 1, Bit_pos + 41, Now_pos)
        end
    ).

-file("src/packkit/internal/bcj.gleam", 850).
?DOC(false).
-spec ia64_decode_bundle(bitstring(), integer()) -> bitstring().
ia64_decode_bundle(Bundle, Now_pos) ->
    case Bundle of
        <<B0, _/binary>> ->
            Template = erlang:'band'(B0, 16#1F),
            Mask = ia64_branch_mask(Template),
            case Mask of
                0 ->
                    Bundle;

                _ ->
                    Byte_list = bit_array_to_byte_list(Bundle, []),
                    Updated = ia64_process_slots(Byte_list, Mask, 0, 5, Now_pos),
                    byte_list_to_bit_array(Updated, <<>>)
            end;

        _ ->
            Bundle
    end.

-file("src/packkit/internal/bcj.gleam", 829).
?DOC(false).
-spec ia64_decode_bundles(bitstring(), integer(), integer(), bitstring()) -> bitstring().
ia64_decode_bundles(Bytes, Start_offset, Bundle_index, Acc) ->
    case Bytes of
        <<Bundle:16/binary, Rest/binary>> ->
            Now_pos = Start_offset + (Bundle_index * 16),
            New_bundle = ia64_decode_bundle(Bundle, Now_pos),
            ia64_decode_bundles(
                Rest,
                Start_offset,
                Bundle_index + 1,
                gleam_stdlib:bit_array_concat([Acc, New_bundle])
            );

        _ ->
            Acc
    end.

-file("src/packkit/internal/bcj.gleam", 807).
?DOC(false).
-spec ia64_decode(bitstring(), integer()) -> bitstring().
ia64_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    Aligned = Total - (Total rem 16),
    case Aligned of
        0 ->
            Bytes;

        _ ->
            case {gleam_stdlib:bit_array_slice(Bytes, 0, Aligned),
                gleam_stdlib:bit_array_slice(Bytes, Aligned, Total - Aligned)} of
                {{ok, Head}, {ok, Tail}} ->
                    Body = ia64_decode_bundles(Head, Start_offset, 0, <<>>),
                    gleam_stdlib:bit_array_concat([Body, Tail]);

                {_, _} ->
                    Bytes
            end
    end.

-file("src/packkit/internal/bcj.gleam", 1097).
?DOC(false).
-spec riscv_decode_jal(
    list(integer()),
    integer(),
    integer(),
    integer(),
    integer(),
    integer()
) -> {list(integer()), integer()}.
riscv_decode_jal(Bytes_list, Pos, B1, B2, B3, Start_offset) ->
    case erlang:'band'(B1, 16#0D) of
        0 ->
            Pc = Start_offset + Pos,
            Addr_a = erlang:'bsl'(erlang:'band'(B1, 16#F0), 13),
            Addr_b = erlang:'bsl'(B2, 9),
            Addr_c = erlang:'bsl'(B3, 1),
            Addr = erlang:'band'(
                (((Addr_a + Addr_b) + Addr_c) - Pc) + 16#100000000,
                16#FFFFFFFF
            ),
            New_b1 = erlang:'bor'(
                erlang:'band'(B1, 16#0F),
                erlang:'band'(erlang:'bsr'(Addr, 8), 16#F0)
            ),
            New_b2 = erlang:'bor'(
                erlang:'bor'(
                    erlang:'band'(erlang:'bsr'(Addr, 16), 16#0F),
                    erlang:'band'(erlang:'bsr'(Addr, 7), 16#10)
                ),
                erlang:'band'(erlang:'bsl'(Addr, 4), 16#E0)
            ),
            New_b3 = erlang:'bor'(
                erlang:'band'(erlang:'bsr'(Addr, 4), 16#7F),
                erlang:'band'(erlang:'bsr'(Addr, 13), 16#80)
            ),
            Updated = list_replace_range(
                Bytes_list,
                Pos + 1,
                [New_b1, New_b2, New_b3]
            ),
            {Updated, 4};

        _ ->
            {Bytes_list, 2}
    end.

-file("src/packkit/internal/bcj.gleam", 1252).
?DOC(false).
-spec not_auipc_pair(integer(), integer()) -> boolean().
not_auipc_pair(Auipc, Inst2) ->
    Shifted = erlang:'band'(erlang:'bsl'(Auipc, 8), 16#FFFFFFFF),
    Diff = erlang:'band'((Inst2 - 3) + 16#100000000, 16#FFFFFFFF),
    erlang:'band'(erlang:'bxor'(Shifted, Diff), 16#F8003) /= 0.

-file("src/packkit/internal/bcj.gleam", 1260).
?DOC(false).
-spec not_special_auipc(integer(), integer()) -> boolean().
not_special_auipc(Auipc, Inst2_rs1) ->
    Diff = erlang:'band'((Auipc - 16#3117) + 16#100000000, 16#FFFFFFFF),
    Lhs = erlang:'band'(erlang:'bsl'(Diff, 18), 16#FFFFFFFF),
    Rhs = erlang:'band'(Inst2_rs1, 16#1D),
    Lhs >= Rhs.

-file("src/packkit/internal/bcj.gleam", 1269).
?DOC(false).
-spec le32_bytes(integer()) -> list(integer()).
le32_bytes(Value) ->
    Masked = erlang:'band'(Value, 16#FFFFFFFF),
    [erlang:'band'(Masked, 16#FF),
        erlang:'band'(erlang:'bsr'(Masked, 8), 16#FF),
        erlang:'band'(erlang:'bsr'(Masked, 16), 16#FF),
        erlang:'band'(erlang:'bsr'(Masked, 24), 16#FF)].

-file("src/packkit/internal/bcj.gleam", 1188).
?DOC(false).
-spec riscv_decode_pair_apply(list(integer()), integer(), integer(), integer()) -> {list(integer()),
    integer()}.
riscv_decode_pair_apply(Bytes_list, Pos, Inst, Inst2) ->
    Addr_base = erlang:'band'(Inst, 16#FFFFF000),
    Addr = erlang:'band'(Addr_base + erlang:'bsr'(Inst2, 20), 16#FFFFFFFF),
    New_inst = erlang:'bor'(
        16#17 + erlang:'bsl'(2, 7),
        erlang:'band'(erlang:'bsl'(Inst2, 12), 16#FFFFFFFF)
    ),
    New_inst2 = Addr,
    Bytes_inst = le32_bytes(New_inst),
    Bytes_inst2 = le32_bytes(New_inst2),
    Updated = list_replace_range(
        Bytes_list,
        Pos,
        lists:append(Bytes_inst, Bytes_inst2)
    ),
    {Updated, 8}.

-file("src/packkit/internal/bcj.gleam", 1178).
?DOC(false).
-spec riscv_decode_pair(list(integer()), integer(), integer(), integer()) -> {list(integer()),
    integer()}.
riscv_decode_pair(Bytes_list, Pos, Inst, Inst2) ->
    gleam@bool:guard(
        not_auipc_pair(Inst, Inst2),
        {Bytes_list, 6},
        fun() -> riscv_decode_pair_apply(Bytes_list, Pos, Inst, Inst2) end
    ).

-file("src/packkit/internal/bcj.gleam", 1210).
?DOC(false).
-spec riscv_decode_special_auipc(
    list(integer()),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer()
) -> {list(integer()), integer()}.
riscv_decode_special_auipc(Bytes_list, Pos, Inst, B4, B5, B6, B7, Start_offset) ->
    Inst2_rs1 = erlang:'bsr'(Inst, 27),
    gleam@bool:guard(
        not_special_auipc(Inst, Inst2_rs1),
        {Bytes_list, 4},
        fun() ->
            Addr_be = ((erlang:'bsl'(B4, 24) + erlang:'bsl'(B5, 16)) + erlang:'bsl'(
                B6,
                8
            ))
            + B7,
            Pc = Start_offset + Pos,
            Addr = erlang:'band'((Addr_be - Pc) + 16#100000000, 16#FFFFFFFF),
            New_inst2 = erlang:'bor'(
                erlang:'bsr'(Inst, 12),
                erlang:'band'(erlang:'bsl'(Addr, 20), 16#FFFFFFFF)
            ),
            Auipc_imm = begin
                _pipe = erlang:'band'(Addr + 16#800, 16#FFFFFFFF),
                erlang:'band'(_pipe, 16#FFFFF000)
            end,
            New_inst = erlang:'bor'(
                erlang:'bor'(16#17, erlang:'bsl'(Inst2_rs1, 7)),
                Auipc_imm
            ),
            Bytes_inst = le32_bytes(New_inst),
            Bytes_inst2 = le32_bytes(New_inst2),
            Updated = list_replace_range(
                Bytes_list,
                Pos,
                lists:append(Bytes_inst, Bytes_inst2)
            ),
            {Updated, 8}
        end
    ).

-file("src/packkit/internal/bcj.gleam", 1139).
?DOC(false).
-spec riscv_decode_auipc(
    list(integer()),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer(),
    integer()
) -> {list(integer()), integer()}.
riscv_decode_auipc(
    Bytes_list,
    Pos,
    B0,
    B1,
    B2,
    B3,
    B4,
    B5,
    B6,
    B7,
    Start_offset
) ->
    Inst = ((B0 + erlang:'bsl'(B1, 8)) + erlang:'bsl'(B2, 16)) + erlang:'bsl'(
        B3,
        24
    ),
    Inst2_le = ((B4 + erlang:'bsl'(B5, 8)) + erlang:'bsl'(B6, 16)) + erlang:'bsl'(
        B7,
        24
    ),
    case erlang:'band'(Inst, 16#E80) of
        0 ->
            riscv_decode_special_auipc(
                Bytes_list,
                Pos,
                Inst,
                B4,
                B5,
                B6,
                B7,
                Start_offset
            );

        _ ->
            riscv_decode_pair(Bytes_list, Pos, Inst, Inst2_le)
    end.

-file("src/packkit/internal/bcj.gleam", 1064).
?DOC(false).
-spec riscv_step(list(integer()), integer(), integer()) -> {list(integer()),
    integer()}.
riscv_step(Bytes_list, Pos, Start_offset) ->
    Slice = list_take_range(Bytes_list, Pos, 8),
    case Slice of
        [B0, B1, B2, B3, B4, B5, B6, B7] ->
            case B0 of
                16#EF ->
                    riscv_decode_jal(Bytes_list, Pos, B1, B2, B3, Start_offset);

                _ ->
                    case erlang:'band'(B0, 16#7F) =:= 16#17 of
                        true ->
                            riscv_decode_auipc(
                                Bytes_list,
                                Pos,
                                B0,
                                B1,
                                B2,
                                B3,
                                B4,
                                B5,
                                B6,
                                B7,
                                Start_offset
                            );

                        false ->
                            {Bytes_list, 2}
                    end
            end;

        _ ->
            {Bytes_list, 2}
    end.

-file("src/packkit/internal/bcj.gleam", 1053).
?DOC(false).
-spec riscv_decode_loop(list(integer()), integer(), integer(), integer()) -> list(integer()).
riscv_decode_loop(Bytes_list, Pos, Limit, Start_offset) ->
    gleam@bool:guard(
        Pos > Limit,
        Bytes_list,
        fun() ->
            {Updated, Advance} = riscv_step(Bytes_list, Pos, Start_offset),
            riscv_decode_loop(Updated, Pos + Advance, Limit, Start_offset)
        end
    ).

-file("src/packkit/internal/bcj.gleam", 1037).
?DOC(false).
-spec riscv_decode(bitstring(), integer()) -> bitstring().
riscv_decode(Bytes, Start_offset) ->
    Aligned_start = erlang:'band'(Start_offset, 16#FFFFFFFF - 1),
    Total = erlang:byte_size(Bytes),
    case Total < 8 of
        true ->
            Bytes;

        false ->
            Byte_list = bit_array_to_byte_list(Bytes, []),
            Decoded = riscv_decode_loop(Byte_list, 0, Total - 8, Aligned_start),
            byte_list_to_bit_array(Decoded, <<>>)
    end.

-file("src/packkit/internal/bcj.gleam", 495).
?DOC(false).
-spec sparc_apply(
    integer(),
    integer(),
    integer(),
    integer(),
    bitstring(),
    integer(),
    integer(),
    bitstring()
) -> bitstring().
sparc_apply(B0, B1, B2, B3, Rest, Start_offset, Word_index, Acc) ->
    Src = begin
        _pipe = erlang:'bor'(
            erlang:'bor'(erlang:'bsl'(B0, 24), erlang:'bsl'(B1, 16)),
            erlang:'bor'(erlang:'bsl'(B2, 8), B3)
        ),
        _pipe@1 = erlang:'bsl'(_pipe, 2),
        erlang:'band'(_pipe@1, 16#FFFFFFFF)
    end,
    Dest = begin
        _pipe@2 = erlang:'band'(
            (Src - (Start_offset + (Word_index * 4))) + 16#100000000,
            16#FFFFFFFF
        ),
        erlang:'bsr'(_pipe@2, 2)
    end,
    Sign_bit = erlang:'band'(erlang:'bsr'(Dest, 22), 1),
    Sign_word = case Sign_bit of
        0 ->
            0;

        _ ->
            16#100000000 - 1
    end,
    Sign_ext = begin
        _pipe@3 = erlang:'band'(erlang:'bsl'(Sign_word, 22), 16#3FFFFFFF),
        erlang:'band'(_pipe@3, 16#FFFFFFFF)
    end,
    Combined = erlang:'bor'(
        erlang:'bor'(Sign_ext, erlang:'band'(Dest, 16#3FFFFF)),
        16#40000000
    ),
    New_b0 = erlang:'band'(erlang:'bsr'(Combined, 24), 16#FF),
    New_b1 = erlang:'band'(erlang:'bsr'(Combined, 16), 16#FF),
    New_b2 = erlang:'band'(erlang:'bsr'(Combined, 8), 16#FF),
    New_b3 = erlang:'band'(Combined, 16#FF),
    sparc_decode_words(
        Rest,
        Start_offset,
        Word_index + 1,
        gleam_stdlib:bit_array_concat([Acc, <<New_b0, New_b1, New_b2, New_b3>>])
    ).

-file("src/packkit/internal/bcj.gleam", 468).
?DOC(false).
-spec sparc_decode_words(bitstring(), integer(), integer(), bitstring()) -> bitstring().
sparc_decode_words(Bytes, Start_offset, Word_index, Acc) ->
    case Bytes of
        <<B0, B1, B2, B3, Rest/binary>> ->
            case is_sparc_call(B0, B1) of
                true ->
                    sparc_apply(
                        B0,
                        B1,
                        B2,
                        B3,
                        Rest,
                        Start_offset,
                        Word_index,
                        Acc
                    );

                false ->
                    sparc_decode_words(
                        Rest,
                        Start_offset,
                        Word_index + 1,
                        gleam_stdlib:bit_array_concat([Acc, <<B0, B1, B2, B3>>])
                    )
            end;

        _ ->
            Acc
    end.

-file("src/packkit/internal/bcj.gleam", 446).
?DOC(false).
-spec sparc_decode(bitstring(), integer()) -> bitstring().
sparc_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    Aligned = Total - (Total rem 4),
    case Aligned of
        0 ->
            Bytes;

        _ ->
            case {gleam_stdlib:bit_array_slice(Bytes, 0, Aligned),
                gleam_stdlib:bit_array_slice(Bytes, Aligned, Total - Aligned)} of
                {{ok, Head}, {ok, Tail}} ->
                    Body = sparc_decode_words(Head, Start_offset, 0, <<>>),
                    gleam_stdlib:bit_array_concat([Body, Tail]);

                {_, _} ->
                    Bytes
            end
    end.

-file("src/packkit/internal/bcj.gleam", 393).
?DOC(false).
-spec armthumb_apply(
    integer(),
    integer(),
    integer(),
    integer(),
    bitstring(),
    integer(),
    integer(),
    integer(),
    bitstring()
) -> bitstring().
armthumb_apply(B0, B1, B2, B3, Rest, Start_offset, Pos, Limit, Acc) ->
    Src = erlang:'bor'(
        erlang:'bor'(
            erlang:'bsl'(erlang:'band'(B1, 7), 19),
            erlang:'bsl'(B0, 11)
        ),
        erlang:'bor'(erlang:'bsl'(erlang:'band'(B3, 7), 8), B2)
    ),
    Src_bytes = erlang:'bsl'(Src, 1),
    Dest = begin
        _pipe = erlang:'band'(
            (Src_bytes - ((Start_offset + Pos) + 4)) + 16#100000000,
            16#FFFFFFFF
        ),
        erlang:'bsr'(_pipe, 1)
    end,
    New_b1 = erlang:'bor'(16#F0, erlang:'band'(erlang:'bsr'(Dest, 19), 16#07)),
    New_b0 = erlang:'band'(erlang:'bsr'(Dest, 11), 16#FF),
    New_b3 = erlang:'bor'(16#F8, erlang:'band'(erlang:'bsr'(Dest, 8), 16#07)),
    New_b2 = erlang:'band'(Dest, 16#FF),
    armthumb_decode_loop(
        Rest,
        Start_offset,
        Pos + 4,
        Limit,
        gleam_stdlib:bit_array_concat([Acc, <<New_b0, New_b1, New_b2, New_b3>>])
    ).

-file("src/packkit/internal/bcj.gleam", 348).
?DOC(false).
-spec armthumb_decode_loop(
    bitstring(),
    integer(),
    integer(),
    integer(),
    bitstring()
) -> bitstring().
armthumb_decode_loop(Remaining, Start_offset, Pos, Limit, Acc) ->
    case Pos > Limit of
        true ->
            gleam_stdlib:bit_array_concat([Acc, Remaining]);

        false ->
            case Remaining of
                <<B0, B1, B2, B3, Rest/binary>> ->
                    case is_armthumb_bl(B1, B3) of
                        true ->
                            armthumb_apply(
                                B0,
                                B1,
                                B2,
                                B3,
                                Rest,
                                Start_offset,
                                Pos,
                                Limit,
                                Acc
                            );

                        false ->
                            armthumb_decode_loop(
                                gleam_stdlib:bit_array_concat(
                                    [<<B2, B3>>, Rest]
                                ),
                                Start_offset,
                                Pos + 2,
                                Limit,
                                gleam_stdlib:bit_array_concat([Acc, <<B0, B1>>])
                            )
                    end;

                _ ->
                    gleam_stdlib:bit_array_concat([Acc, Remaining])
            end
    end.

-file("src/packkit/internal/bcj.gleam", 337).
?DOC(false).
-spec armthumb_decode(bitstring(), integer()) -> bitstring().
armthumb_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    case Total < 4 of
        true ->
            Bytes;

        false ->
            armthumb_decode_loop(Bytes, Start_offset, 0, Total - 4, <<>>)
    end.

-file("src/packkit/internal/bcj.gleam", 289).
?DOC(false).
-spec powerpc_apply(
    integer(),
    integer(),
    integer(),
    integer(),
    bitstring(),
    integer(),
    integer(),
    bitstring()
) -> bitstring().
powerpc_apply(B0, B1, B2, B3, Rest, Start_offset, Word_index, Acc) ->
    Src = erlang:'bor'(
        erlang:'bor'(
            erlang:'bsl'(erlang:'band'(B0, 3), 24),
            erlang:'bsl'(B1, 16)
        ),
        erlang:'bor'(erlang:'bsl'(B2, 8), erlang:'band'(B3, 16#FC))
    ),
    Dest = erlang:'band'(
        (Src - (Start_offset + (Word_index * 4))) + 16#100000000,
        16#FFFFFFFF
    ),
    New_b0 = erlang:'bor'(16#48, erlang:'band'(erlang:'bsr'(Dest, 24), 16#03)),
    New_b1 = erlang:'band'(erlang:'bsr'(Dest, 16), 16#FF),
    New_b2 = erlang:'band'(erlang:'bsr'(Dest, 8), 16#FF),
    New_b3 = erlang:'bor'(erlang:'band'(B3, 16#03), erlang:'band'(Dest, 16#FC)),
    powerpc_decode_words(
        Rest,
        Start_offset,
        Word_index + 1,
        gleam_stdlib:bit_array_concat([Acc, <<New_b0, New_b1, New_b2, New_b3>>])
    ).

-file("src/packkit/internal/bcj.gleam", 257).
?DOC(false).
-spec powerpc_decode_words(bitstring(), integer(), integer(), bitstring()) -> bitstring().
powerpc_decode_words(Bytes, Start_offset, Word_index, Acc) ->
    case Bytes of
        <<B0, B1, B2, B3, Rest/binary>> ->
            case is_powerpc_branch_link(B0, B3) of
                false ->
                    powerpc_decode_words(
                        Rest,
                        Start_offset,
                        Word_index + 1,
                        gleam_stdlib:bit_array_concat([Acc, <<B0, B1, B2, B3>>])
                    );

                true ->
                    powerpc_apply(
                        B0,
                        B1,
                        B2,
                        B3,
                        Rest,
                        Start_offset,
                        Word_index,
                        Acc
                    )
            end;

        _ ->
            Acc
    end.

-file("src/packkit/internal/bcj.gleam", 235).
?DOC(false).
-spec powerpc_decode(bitstring(), integer()) -> bitstring().
powerpc_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    Aligned = Total - (Total rem 4),
    case Aligned of
        0 ->
            Bytes;

        _ ->
            case {gleam_stdlib:bit_array_slice(Bytes, 0, Aligned),
                gleam_stdlib:bit_array_slice(Bytes, Aligned, Total - Aligned)} of
                {{ok, Head}, {ok, Tail}} ->
                    Body = powerpc_decode_words(Head, Start_offset, 0, <<>>),
                    gleam_stdlib:bit_array_concat([Body, Tail]);

                {_, _} ->
                    Bytes
            end
    end.

-file("src/packkit/internal/bcj.gleam", 96).
?DOC(false).
-spec x86_try_decode_call(
    list(integer()),
    integer(),
    integer(),
    integer(),
    x86_state(),
    list(integer())
) -> list(integer()).
x86_try_decode_call(Remaining, Buffer_pos, Limit, Now_pos, State, Acc_reversed) ->
    Offset = (Now_pos + Buffer_pos) - erlang:element(2, State),
    Prev_pos_after = Now_pos + Buffer_pos,
    Prev_mask_after = case Offset > 5 of
        true ->
            0;

        false ->
            shift_mask_left(erlang:element(3, State), Offset)
    end,
    {Opcode, D0, D1, D2, D3, Tail} = case Remaining of
        [Op, B0, B1, B2, B3 | Rest] ->
            {Op, B0, B1, B2, B3, Rest};

        _ ->
            {0, 0, 0, 0, 0, []}
    end,
    case is_decodable(D3, Prev_mask_after) of
        false ->
            Bumped = case test_msb(D3) of
                true ->
                    erlang:'bor'(erlang:'bor'(Prev_mask_after, 1), 16#10);

                false ->
                    erlang:'bor'(Prev_mask_after, 1)
            end,
            x86_decode_loop(
                [D0, D1, D2, D3 | Tail],
                Buffer_pos + 1,
                Limit,
                Now_pos,
                {x86_state, Prev_pos_after, Bumped},
                [Opcode | Acc_reversed]
            );

        true ->
            Src = erlang:'bor'(
                erlang:'bor'(erlang:'bsl'(D3, 24), erlang:'bsl'(D2, 16)),
                erlang:'bor'(erlang:'bsl'(D1, 8), D0)
            ),
            Dest = x86_resolve_dest(
                Src,
                (Now_pos + Buffer_pos) + 5,
                Prev_mask_after
            ),
            New_d3 = case erlang:'band'(erlang:'bsr'(Dest, 24), 1) of
                0 ->
                    0;

                _ ->
                    16#FF
            end,
            New_d0 = erlang:'band'(Dest, 16#FF),
            New_d1 = erlang:'band'(erlang:'bsr'(Dest, 8), 16#FF),
            New_d2 = erlang:'band'(erlang:'bsr'(Dest, 16), 16#FF),
            x86_decode_loop(
                Tail,
                Buffer_pos + 5,
                Limit,
                Now_pos,
                {x86_state, Prev_pos_after, 0},
                [New_d3, New_d2, New_d1, New_d0, Opcode | Acc_reversed]
            )
    end.

-file("src/packkit/internal/bcj.gleam", 58).
?DOC(false).
-spec x86_decode_loop(
    list(integer()),
    integer(),
    integer(),
    integer(),
    x86_state(),
    list(integer())
) -> list(integer()).
x86_decode_loop(Remaining, Buffer_pos, Limit, Now_pos, State, Acc_reversed) ->
    case Remaining of
        [] ->
            lists:reverse(Acc_reversed);

        [Byte_at_pos | Rest] ->
            case Buffer_pos > Limit of
                true ->
                    lists:append(lists:reverse(Acc_reversed), Remaining);

                false ->
                    case Byte_at_pos of
                        16#E8 ->
                            x86_try_decode_call(
                                Remaining,
                                Buffer_pos,
                                Limit,
                                Now_pos,
                                State,
                                Acc_reversed
                            );

                        16#E9 ->
                            x86_try_decode_call(
                                Remaining,
                                Buffer_pos,
                                Limit,
                                Now_pos,
                                State,
                                Acc_reversed
                            );

                        _ ->
                            x86_decode_loop(
                                Rest,
                                Buffer_pos + 1,
                                Limit,
                                Now_pos,
                                State,
                                [Byte_at_pos | Acc_reversed]
                            )
                    end
            end
    end.

-file("src/packkit/internal/bcj.gleam", 29).
?DOC(false).
-spec x86_decode(bitstring(), integer()) -> bitstring().
x86_decode(Bytes, Start_offset) ->
    Total = erlang:byte_size(Bytes),
    case Total < 5 of
        true ->
            Bytes;

        false ->
            Byte_list = bit_array_to_byte_list(Bytes, []),
            Initial = {x86_state, Start_offset - 5, 0},
            Limit = Total - 5,
            Decoded = x86_decode_loop(
                Byte_list,
                0,
                Limit,
                Start_offset,
                Initial,
                []
            ),
            byte_list_to_bit_array(Decoded, <<>>)
    end.