// ARM64Constants.swift — Pre-encoded ARM64 instruction constants.
//
// Every constant was generated by keystone-engine and verified
// via capstone round-trip disassembly. Do NOT edit raw bytes
// without updating the corresponding test case.

import Foundation

// MARK: - ARM64 Instruction Constants

public enum ARM64 {
    // MARK: Fixed Instructions

    /// NOP — no operation
    public static let nop = encodeU32(0xD503_201F)

    /// RET — return from subroutine
    public static let ret = encodeU32(0xD65F_03C0)

    /// RETAA — return with pointer authentication (A key)
    public static let retaa = encodeU32(0xD65F_0BFF)

    /// RETAB — return with pointer authentication (B key)
    public static let retab = encodeU32(0xD65F_0FFF)

    /// PACIBSP — sign LR with B key using SP (hint #27)
    public static let pacibsp = encodeU32(0xD503_237F)

    // MARK: MOV Variants

    /// MOV X0, #0  (MOVZ X0, #0)
    public static let movX0_0 = encodeU32(0xD280_0000)

    /// MOV X0, #1  (MOVZ X0, #1)
    public static let movX0_1 = encodeU32(0xD280_0020)

    /// MOV W0, #0  (MOVZ W0, #0)
    public static let movW0_0 = encodeU32(0x5280_0000)

    /// MOV W0, #1  (MOVZ W0, #1)
    public static let movW0_1 = encodeU32(0x5280_0020)

    /// MOV X0, X20  (ORR X0, XZR, X20)
    public static let movX0X20 = encodeU32(0xAA14_03E0)

    /// MOV W0, #0xA1  (MOVZ W0, #0xA1)
    public static let movW0_0xA1 = encodeU32(0x5280_1420)

    // MARK: Compare

    /// CMP W0, W0  (SUBS WZR, W0, W0)
    public static let cmpW0W0 = encodeU32(0x6B00_001F)

    /// CMP X0, X0  (SUBS XZR, X0, X0)
    public static let cmpX0X0 = encodeU32(0xEB00_001F)

    // MARK: Memory

    /// STRB W0, [X20, #0x30]
    public static let strbW0X20_30 = encodeU32(0x3900_C280)

    // MARK: JB Constants

    /// CBZ X2, #8  (branch if X2 == 0, skip 2 instructions)
    public static let cbzX2_8 = encodeU32(0xB400_0042)

    /// STR X0, [X2]
    public static let strX0X2 = encodeU32(0xF900_0040)

    /// CMP XZR, XZR  (SUBS XZR, XZR, XZR — always sets Z flag)
    public static let cmpXzrXzr = encodeU32(0xEB1F_03FF)

    // MARK: Common Prologue/Epilogue Patterns (verified via keystone)

    /// STP X29, X30, [SP, #-0x10]!  (push frame)
    static let stpFP_LR_pre: UInt32 = 0xA9BF_7BFD
    /// MOV X29, SP  (set frame pointer)
    static let movFP_SP: UInt32 = 0x9100_03FD

    // MARK: IOUC MACF Aggregator Shape

    /// LDR X10, [X10, #0x9E8]  (mac_policy_list slot load)
    static let ldr_x10_x10_0x9e8: UInt32 = 0xF944_F54A
    /// BLRAA X10, SP  (authenticated indirect call)
    static let blraa_x10: UInt32 = 0xD73F_0940
    /// BLRAB X10, SP
    static let blrab_x10: UInt32 = 0xD73F_0D40
    /// BLR X10
    static let blr_x10: UInt32 = 0xD63F_0140

    // MARK: C23 Cave Instructions (verified via keystone)

    //
    // These are the fixed instructions used in the faithful upstream C23
    // shellcode cave (vnode getattr → uid/gid/P_SUGID fixup).
    // Position-dependent BL/B instructions are NOT included here — they are
    // encoded at build time by ARM64Encoder.

    static let c23_cbzX3_0xA8: UInt32 = 0xB400_0543 // cbz x3, #+0xa8
    static let c23_subSP_0x400: UInt32 = 0xD110_03FF // sub sp, sp, #0x400
    static let c23_stpFP_LR: UInt32 = 0xA900_7BFD // stp x29, x30, [sp]
    static let c23_stpX0X1_0x10: UInt32 = 0xA901_07E0 // stp x0, x1, [sp, #0x10]
    static let c23_stpX2X3_0x20: UInt32 = 0xA902_0FE2 // stp x2, x3, [sp, #0x20]
    static let c23_stpX4X5_0x30: UInt32 = 0xA903_17E4 // stp x4, x5, [sp, #0x30]
    static let c23_stpX6X7_0x40: UInt32 = 0xA904_1FE6 // stp x6, x7, [sp, #0x40]
    static let c23_movX2_X0: UInt32 = 0xAA00_03E2 // mov x2, x0
    static let c23_ldrX0_sp_0x28: UInt32 = 0xF940_17E0 // ldr x0, [sp, #0x28]
    static let c23_addX1_sp_0x80: UInt32 = 0x9102_03E1 // add x1, sp, #0x80
    static let c23_movzW8_0x380: UInt32 = 0x5280_7008 // movz w8, #0x380
    static let c23_stpXZR_X8: UInt32 = 0xA900_203F // stp xzr, x8, [x1]
    static let c23_stpXZR_XZR_0x10: UInt32 = 0xA901_7C3F // stp xzr, xzr, [x1, #0x10]
    static let c23_cbnzX0_0x4c: UInt32 = 0xB500_0260 // cbnz x0, #+0x4c
    static let c23_movW2_0: UInt32 = 0x5280_0002 // mov w2, #0
    static let c23_ldrW8_sp_0xcc: UInt32 = 0xB940_CFE8 // ldr w8, [sp, #0xcc]
    static let c23_tbzW8_11_0x14: UInt32 = 0x3658_00A8 // tbz w8, #0xb, #+0x14
    static let c23_ldrW8_sp_0xc4: UInt32 = 0xB940_C7E8 // ldr w8, [sp, #0xc4]
    static let c23_ldrX0_sp_0x18: UInt32 = 0xF940_0FE0 // ldr x0, [sp, #0x18]
    static let c23_strW8_x0_0x18: UInt32 = 0xB900_1808 // str w8, [x0, #0x18]
    static let c23_movW2_1: UInt32 = 0x5280_0022 // mov w2, #1
    static let c23_tbzW8_10_0x14: UInt32 = 0x3650_00A8 // tbz w8, #0xa, #+0x14
    static let c23_ldrW8_sp_0xc8: UInt32 = 0xB940_CBE8 // ldr w8, [sp, #0xc8]
    static let c23_strW8_x0_0x28: UInt32 = 0xB900_2808 // str w8, [x0, #0x28]
    static let c23_cbzW2_0x14: UInt32 = 0x3400_00A2 // cbz w2, #+0x14
    static let c23_ldrX0_sp_0x20: UInt32 = 0xF940_13E0 // ldr x0, [sp, #0x20]
    static let c23_ldrW8_x0_0x454: UInt32 = 0xB944_5408 // ldr w8, [x0, #0x454]
    static let c23_orrW8_0x100: UInt32 = 0x3218_0108 // orr w8, w8, #0x100
    static let c23_strW8_x0_0x454: UInt32 = 0xB904_5408 // str w8, [x0, #0x454]
    static let c23_ldpX0X1_0x10: UInt32 = 0xA941_07E0 // ldp x0, x1, [sp, #0x10]
    static let c23_ldpX2X3_0x20: UInt32 = 0xA942_0FE2 // ldp x2, x3, [sp, #0x20]
    static let c23_ldpX4X5_0x30: UInt32 = 0xA943_17E4 // ldp x4, x5, [sp, #0x30]
    static let c23_ldpX6X7_0x40: UInt32 = 0xA944_1FE6 // ldp x6, x7, [sp, #0x40]
    static let c23_ldpFP_LR: UInt32 = 0xA940_7BFD // ldp x29, x30, [sp]
    static let c23_addSP_0x400: UInt32 = 0x9110_03FF // add sp, sp, #0x400

    // MARK: vfs_context_current Shape (verified via keystone)

    /// mrs x0, tpidr_el1
    static let mrs_x0_tpidr_el1: UInt32 = 0xD538_D080

    // MARK: Syscallmask C22 Cave Instructions (verified via clang/as)

    static let syscallmask_cbzX2_0x6c: UInt32 = 0xB400_0362 // cbz x2, #+0x6c
    static let syscallmask_subSP_0x40: UInt32 = 0xD101_03FF // sub sp, sp, #0x40
    static let syscallmask_stpX19X20_0x10: UInt32 = 0xA901_53F3 // stp x19, x20, [sp, #0x10]
    static let syscallmask_stpX21X22_0x20: UInt32 = 0xA902_5BF5 // stp x21, x22, [sp, #0x20]
    static let syscallmask_stpFP_LR_0x30: UInt32 = 0xA903_7BFD // stp x29, x30, [sp, #0x30]
    static let syscallmask_movX19_X0: UInt32 = 0xAA00_03F3 // mov x19, x0
    static let syscallmask_movX20_X1: UInt32 = 0xAA01_03F4 // mov x20, x1
    static let syscallmask_movX21_X2: UInt32 = 0xAA02_03F5 // mov x21, x2
    static let syscallmask_movX22_X3: UInt32 = 0xAA03_03F6 // mov x22, x3
    static let syscallmask_movX8_8: UInt32 = 0xD280_0108 // mov x8, #8
    static let syscallmask_movX0_X17: UInt32 = 0xAA11_03E0 // mov x0, x17
    static let syscallmask_movX1_X21: UInt32 = 0xAA15_03E1 // mov x1, x21
    static let syscallmask_movX2_0: UInt32 = 0xD280_0002 // mov x2, #0
    static let syscallmask_udivX4_X22_X8: UInt32 = 0x9AC8_0AC4 // udiv x4, x22, x8
    static let syscallmask_msubX10_X4_X8_X22: UInt32 = 0x9B08_D88A // msub x10, x4, x8, x22
    static let syscallmask_cbzX10_8: UInt32 = 0xB400_004A // cbz x10, #+8
    static let syscallmask_addX4_X4_1: UInt32 = 0x9100_0484 // add x4, x4, #1
    static let syscallmask_movX0_X19: UInt32 = 0xAA13_03E0 // mov x0, x19
    static let syscallmask_movX1_X20: UInt32 = 0xAA14_03E1 // mov x1, x20
    static let syscallmask_movX2_X21: UInt32 = 0xAA15_03E2 // mov x2, x21
    static let syscallmask_movX3_X22: UInt32 = 0xAA16_03E3 // mov x3, x22
    static let syscallmask_ldpX19X20_0x10: UInt32 = 0xA941_53F3 // ldp x19, x20, [sp, #0x10]
    static let syscallmask_ldpX21X22_0x20: UInt32 = 0xA942_5BF5 // ldp x21, x22, [sp, #0x20]
    static let syscallmask_ldpFP_LR_0x30: UInt32 = 0xA943_7BFD // ldp x29, x30, [sp, #0x30]
    static let syscallmask_addSP_0x40: UInt32 = 0x9101_03FF // add sp, sp, #0x40

    // MARK: UInt32 Values (for pattern matching)

    public static let nopU32: UInt32 = 0xD503_201F
    public static let retU32: UInt32 = 0xD65F_03C0
    public static let retaaU32: UInt32 = 0xD65F_0BFF
    public static let retabU32: UInt32 = 0xD65F_0FFF
    public static let pacibspU32: UInt32 = 0xD503_237F
    public static let movX0_0_U32: UInt32 = 0xD280_0000 // MOV X0, #0 (MOVZ X0, #0)

    /// Set of instruction uint32 values that indicate function boundaries.
    public static let funcBoundaryU32s: Set<UInt32> = [
        retU32, retaaU32, retabU32, pacibspU32,
    ]

    // MARK: - Helpers

    @inlinable
    static func encodeU32(_ value: UInt32) -> Data {
        withUnsafeBytes(of: value.littleEndian) { Data($0) }
    }
}
