ARM_PATTERNS: list[InstrPattern] = [InstrPattern(3840, 3840, arm_software_interrupt), InstrPattern(3584, 2560, arm_branch), InstrPattern(3584, 2048, arm_block_data_transfer), InstrPattern(3072, 1024, arm_single_data_transfer), InstrPattern(4095, 289, arm_branch_exchange), InstrPattern(4031, 265, arm_single_data_swap), InstrPattern(3983, 137, arm_multiply_long), InstrPattern(4047, 9, arm_multiply), InstrPattern(3593, 9, arm_halfword_data_transfer), InstrPattern(3504, 256, arm_mrs), InstrPattern(3504, 288, arm_msr), InstrPattern(3072, 0, arm_alu)]

def fill_arm_lut():
    for lut_index in range(2 ** 12):
        for pattern in ARM_PATTERNS:
            if lut_index & pattern.mask == pattern.value:
                ARM_LUT[lut_index] = pattern.handler
                break
fill_arm_lut()

def arm_decoder(instr: int) -> InstrHandler:
    opcode_hash = instr >> 16 & 4080 | instr >> 4 & 15
    instruction_handler = ARM_LUT[opcode_hash]
    return instruction_handler