Sign in

    x64_target

    x64 ISA target for lowering MilkIR into MachV

    x64
    x86-64
    compiler
    codegen
    Download zip
    Author
    Version
    0.1.2
    License
    Apache-2.0
    Last updated
    3 months ago
    Downloads
    208

    #x64_target

    x64 target support for MilkIR-to-MachV lowering.

    This module provides x86-64 ABI policy, machine-environment construction, and target lowering hooks used by the generic MilkIR-to-MachV lowering pipeline.

    #Package

    • Milky2018/x64_target: x64 target descriptor, ABI policy, machine environment, and lowering entry points.

    #When to use it

    Use this module when you want x86-64 target policy: System V register assignment, callee-saved sets, allocatable registers, and convenience lowering from MilkIR to MachV.

    #Example: inspect System V policy

    The target API exposes the ABI details a compiler backend needs before register allocation and emission.

    ///|
    test "inspect x64 ABI policy" {
    let abi = abi_policy()
    inspect(abi.pointer_size, content="8")
    inspect(abi.stack_alignment, content="16")
    inspect(abi.int_argument_regs.length(), content="6")
    inspect(abi.float_argument_regs.length(), content="8")
    }

    #Example: lower MilkIR through the x64 target

    The wrapper returns MachV with x64-specific instruction choices and ABI locations.

    ///|
    test "lower an integer add function for x64" {
    let builder = @milkir.FunctionBuilder::FunctionBuilder("add64")
    let lhs = builder.add_param(I64)
    let rhs = builder.add_param(I64)
    builder.add_result(I64)
    builder.return_([builder.iadd(lhs, rhs)])
    let lowered = lower_function(builder.get_function())
    inspect(lowered.name, content="add64")
    inspect(lowered.blocks.length(), content="1")
    inspect(
    lowered.blocks[0].insts.any(fn(inst) { inst.opcode is Add(_) }),
    content="true",
    )
    }

    #Example: lower with a custom call convention

    Embedders that use their own context register and argument order can pass an explicit call-convention layout.

    ///|
    test "lower x64 with an explicit call convention" {
    let builder = @milkir.FunctionBuilder::FunctionBuilder("custom_add64")
    let context = builder.add_param(Ptr)
    let lhs = builder.add_param(I64)
    let rhs = builder.add_param(I64)
    builder.add_result(I64)
    builder.return_([builder.iadd(lhs, rhs)])
    context |> ignore
    let conv : @abi.CallConventionLayout = {
    context_arg: { index: 7, class: Int },
    user_arg_gprs: [{ index: 6, class: Int }, { index: 2, class: Int }],
    arg_fprs: [],
    ret_gprs: [{ index: 0, class: Int }],
    ret_fprs: [],
    }
    let lowered = lower_function_with_call_conv(builder.get_function(), conv)
    inspect(lowered.name, content="custom_add64")
    inspect(lowered.blocks.length(), content="1")
    }

    #Integration

    Use this package with Milky2018/milkir_machv for x64 instruction selection and Milky2018/machv_emit for final machine-code emission. Runtime symbols and executable-memory allocation are supplied by the embedding application after emission.

    AbiPolicy

    pub(all) struct AbiPolicy {
    pointer_size : Int
    stack_alignment : Int
    int_argument_regs : Array[
    PReg
    ]
    float_argument_regs : Array[
    PReg
    ]
    int_return_regs : Array[
    PReg
    ]
    float_return_regs : Array[
    PReg
    ]
    caller_saved_regs : Array[
    PReg
    ]
    callee_saved_regs : Array[
    PReg
    ]
    } derive(
    Debug
    )

    CallingConvention

    pub(all) enum CallingConvention {
    SystemV
    } derive(Eq,
    Debug
    )

    IntRegRole

    pub(all) enum IntRegRole {
    Scratch1
    Scratch2
    FP
    LR
    SRet
    } derive(Eq,
    Debug
    )

    MachineEnvData

    pub(all) struct MachineEnvData {
    preferred_int : Array[
    PReg
    ]
    nonpreferred_int : Array[
    PReg
    ]
    preferred_float : Array[
    PReg
    ]
    nonpreferred_float : Array[
    PReg
    ]
    preferred_vector : Array[
    PReg
    ]
    nonpreferred_vector : Array[
    PReg
    ]
    callee_saved_int : Array[
    PReg
    ]
    callee_saved_float : Array[
    PReg
    ]
    scratch_int : Array[Int]
    scratch_float : Array[Int]
    } derive(
    Debug
    )

    Target

    pub(all) struct Target {
    triple : String
    calling_convention : CallingConvention
    abi : AbiPolicy
    } derive(
    Debug
    )

    abi_policy

    fn abi_policy() -> AbiPolicy

    allocatable_callee_saved_regs

    fn allocatable_callee_saved_regs() -> Array[
    PReg
    ]

    allocatable_regs

    fn allocatable_regs(reserved_int_regs? : Array[Int]) -> Array[
    PReg
    ]

    allocatable_scratch_fprs

    fn allocatable_scratch_fprs() -> Array[
    PReg
    ]

    allocatable_scratch_regs

    fn allocatable_scratch_regs() -> Array[
    PReg
    ]

    build_machine_env

    fn build_machine_env(reserved_int_regs? : Array[Int]) -> MachineEnvData

    call_clobbered_fprs

    fn call_clobbered_fprs() -> Array[
    PReg
    ]

    call_clobbered_fprs_same_abi

    fn call_clobbered_fprs_same_abi() -> Array[
    PReg
    ]

    call_clobbered_gprs

    fn call_clobbered_gprs() -> Array[
    PReg
    ]

    int_reg_index

    fn int_reg_index(role : IntRegRole) -> Int

    lower_function

    lower_function_with_call_conv

    sysv_arg_fprs

    fn sysv_arg_fprs() -> Array[
    PReg
    ]

    sysv_callee_saved

    fn sysv_callee_saved() -> Array[
    PReg
    ]

    target

    fn target() -> Target

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io