diff --git a/src/LLVM.zig b/src/LLVM.zig index 778fb48..e69b039 100644 --- a/src/LLVM.zig +++ b/src/LLVM.zig @@ -1,11 +1,12 @@ const lib = @import("lib.zig"); const Arena = lib.Arena; +const assert = lib.assert; const api = @import("llvm_api.zig"); /// This is a String which ABI-compatible with C++ pub const String = extern struct { - pointer: [*]const u8, - length: usize, + pointer: ?[*]const u8 = null, + length: usize = 0, pub fn from_slice(slice: []const u8) String { return String{ @@ -14,8 +15,12 @@ pub const String = extern struct { }; } - pub fn to_slice(string: String) []const u8 { - return string.pointer[0..string.length]; + pub fn to_slice(string: String) ?[]const u8 { + if (string.length != 0) { + return string.pointer.?[0..string.length]; + } else { + return null; + } } }; @@ -29,8 +34,8 @@ pub const CodeModel = enum(u8) { }; pub const RelocationModel = enum(u8) { - default_relocation = 0, - static_relocation = 1, + default = 0, + static = 1, pic = 2, dynamic_no_pic = 3, ropi = 4, @@ -41,27 +46,201 @@ pub const RelocationModel = enum(u8) { pub const CodeGenerationOptimizationLevel = enum(u8) { none = 0, // -O0 less = 1, // -O1 - normal = 2, // -O2, -Os + default = 2, // -O2, -Os aggressive = 3, // -O3 }; -/// This is ABI-compatible with C++ -pub const TargetOptions = extern struct { - reserved: u32, +pub const Target = opaque { + /// This is ABI-compatible with C++ + pub const Options = extern struct { + flags0: packed struct(u64) { + unsafe_fp_math: u1, + no_infs_fp_math: u1, + no_nans_fp_math: u1, + no_trapping_fp_math: u1, + no_signed_zeroes_fp_math: u1, + approx_func_fp_match: u1, + enable_aix_extended_altivec_abi: u1, + honor_sign_dependent_rounding_fp_math: u1, + no_zeroes_in_bss: u1, + guaranteed_tail_call_optimization: u1, + stack_symbol_ordering: u1, + enable_fast_isel: u1, + enable_global_isel: u1, + global_isel_abort_mode: enum(u2) { + disable = 0, + enable = 1, + disable_with_diag = 2, + }, + swift_async_frame_pointer: enum(u2) { + deployment_based = 0, + always = 1, + never = 2, + }, + use_init_array: u1, + disabled_integrated_assembler: u1, + function_sections: u1, + data_sections: u1, + ignore_xcoff_visibility: u1, + xcoff_traceback_table: u1, + unique_section_names: u1, + unique_basic_block_section_names: u1, + separate_named_sections: u1, + trap_unreachable: u1, + no_trap_after_noreturn: u1, + tls_size: u8, + emulated_tls: u1, + enable_tls_descriptors: u1, + enable_ipra: u1, + emit_stack_size_section: u1, + enable_machine_outliner: u1, + enable_machine_function_splitter: u1, + supports_default_outlining: u1, + emit_address_significance_table: u1, + bb_address_map: u1, + bb_sections: enum(u3) { + all = 0, + list = 1, + labels = 2, + preset = 3, + none = 4, + }, + emit_call_site_information: u1, + supports_debug_entry_values: u1, + enable_debug_entry_values: u1, + value_tracking_variable_locations: u1, + force_dwarf_frame_section: u1, + xray_function_index: u1, + debug_strict_dwarf: u1, + hotpatch: u1, + ppc_gen_scalar_mass_entries: u1, + jmc_instrument: u1, + enable_cfi_fixup: u1, + mis_expect: u1, + xcoff_read_only_pointers: u1, + float_abi: enum(u2) { + default = 0, + soft = 1, + hard = 2, + }, + thread_model: enum(u1) { + posix = 0, + single = 1, + }, + }, + flags1: packed struct(u32) { + fp_op_fusion_mode: enum(u2) { + fast = 0, + standard = 1, + strict = 2, + }, + eabi_version: enum(u3) { + unknown = 0, + default = 1, + eabi4 = 2, + eabi5 = 3, + gnu = 4, + }, + debugger_kind: enum(u3) { + default = 0, + gdb = 1, + lldb = 2, + sce = 3, + dbx = 4, + }, + exception_handling: enum(u3) { + none = 0, + dwarf_cfi = 1, + setjmp_longjmp = 2, + arm = 3, + win_eh = 4, + wasm = 5, + aix = 6, + zos = 7, + }, + reserved: u21 = 0, + }, + loop_alignment: c_uint, + binutils_version: [2]c_int, + mc: MCTargetOptions, + }; + + pub const Machine = opaque { + /// This is ABI-compatible with C++ + pub const Create = extern struct { + target_options: Target.Options, + cpu_triple: String, + cpu_model: String, + cpu_features: String, + code_model: CodeModel, + relocation_model: RelocationModel, + optimization_level: CodeGenerationOptimizationLevel, + jit: bool, + reserved: u32 = 0, + }; + + comptime { + assert(@sizeOf(Create) == 192); + } + + pub fn create(options: Create, error_message: *String) ?*Target.Machine { + const target_machine = api.llvm_create_target_machine(&options, error_message); + return target_machine; + } + }; +}; +pub const MCTargetOptions = extern struct { + abi_name: String, + assembly_language: String, + split_dwarf_file: String, + as_secure_log_file: String, + argv0: ?[*:0]const u8, + argv_pointer: ?[*]const String, + argv_count: u64, + integrated_assembler_search_path_pointer: ?[*]const String, + integrated_assembler_search_path_count: u64, + flags: packed struct(u32) { + relax_all: u1, + no_exec_stack: u1, + fatal_warnings: u1, + no_warn: u1, + no_deprecated_warn: u1, + no_type_check: u1, + save_temp_labels: u1, + incremental_linker_compatible: u1, + fdpic: u1, + show_mc_encoding: u1, + show_mc_inst: u1, + asm_verbose: u1, + preserve_asm_comments: u1, + dwarf64: u1, + crel: u1, + x86_relax_relocations: u1, + x86_sse2_avx: u1, + emit_dwarf_unwind: enum(u2) { + always = 0, + no_compact_unwind = 1, + default = 2, + }, + use_dwarf_directory: enum(u2) { + disable = 0, + enable = 1, + default = 2, + }, + debug_compression_type: enum(u2) { + none = 0, + zlib = 1, + zstd = 2, + }, + emit_compact_unwind_non_canonical: u1, + ppc_use_full_register_names: u1, + reserved: u7 = 0, + }, }; -/// This is ABI-compatible with C++ -pub const TargetMachineCreate = extern struct { - target_options: TargetOptions, - cpu_triple: String, - cpu_model: String, - cpu_features: String, - code_model: CodeModel, - relocation_model: RelocationModel, - optimization_level: CodeGenerationOptimizationLevel, - jit: bool, - reserved: u32, -}; +comptime { + assert(@sizeOf(MCTargetOptions) == 112); +} pub const Architecture = enum { X86, @@ -94,7 +273,7 @@ pub const Module = opaque { pub const create_di_builder = api.LLVMCreateDIBuilder; pub fn to_string(module: *Module) []const u8 { - return api.llvm_module_to_string(module).to_slice(); + return api.llvm_module_to_string(module).to_slice().?; } const FunctionCreate = struct { @@ -118,7 +297,7 @@ pub const Module = opaque { }; pub const VerifyResult = struct { - error_message: []const u8, + error_message: ?[]const u8, success: bool, }; @@ -316,9 +495,9 @@ pub fn initialize_all() void { global = .{ .threads = lib.global.arena.allocate(Thread, lib.global.thread_count), - .host_triple = api.llvm_default_target_triple().to_slice(), - .host_cpu_model = api.llvm_host_cpu_name().to_slice(), - .host_cpu_features = api.llvm_host_cpu_features().to_slice(), + .host_triple = api.llvm_default_target_triple().to_slice() orelse unreachable, + .host_cpu_model = api.llvm_host_cpu_name().to_slice() orelse unreachable, + .host_cpu_features = api.llvm_host_cpu_features().to_slice() orelse unreachable, }; } @@ -351,4 +530,117 @@ pub fn experiment() void { const module_string = module.to_string(); lib.print_string(module_string); + + var error_message: String = undefined; + const target_machine = Target.Machine.create(.{ + .target_options = .{ + .binutils_version = .{ 0, 0 }, + .flags0 = .{ + .unsafe_fp_math = 0, + .no_infs_fp_math = 0, + .no_nans_fp_math = 0, + .no_trapping_fp_math = 1, + .no_signed_zeroes_fp_math = 0, + .approx_func_fp_match = 0, + .enable_aix_extended_altivec_abi = 0, + .honor_sign_dependent_rounding_fp_math = 0, + .no_zeroes_in_bss = 0, + .guaranteed_tail_call_optimization = 0, + .stack_symbol_ordering = 1, + .enable_fast_isel = 0, + .enable_global_isel = 0, + .global_isel_abort_mode = .enable, + .swift_async_frame_pointer = .always, + .use_init_array = 0, + .disabled_integrated_assembler = 0, + .function_sections = 0, + .data_sections = 0, + .ignore_xcoff_visibility = 0, + .xcoff_traceback_table = 1, + .unique_section_names = 1, + .unique_basic_block_section_names = 0, + .separate_named_sections = 0, + .trap_unreachable = 0, + .no_trap_after_noreturn = 0, + .tls_size = 0, + .emulated_tls = 0, + .enable_tls_descriptors = 0, + .enable_ipra = 0, + .emit_stack_size_section = 0, + .enable_machine_outliner = 0, + .enable_machine_function_splitter = 0, + .supports_default_outlining = 0, + .emit_address_significance_table = 0, + .bb_address_map = 0, + .bb_sections = .none, + .emit_call_site_information = 0, + .supports_debug_entry_values = 0, + .enable_debug_entry_values = 0, + .value_tracking_variable_locations = 0, + .force_dwarf_frame_section = 0, + .xray_function_index = 1, + .debug_strict_dwarf = 0, + .hotpatch = 0, + .ppc_gen_scalar_mass_entries = 0, + .jmc_instrument = 0, + .enable_cfi_fixup = 0, + .mis_expect = 0, + .xcoff_read_only_pointers = 0, + .float_abi = .default, + .thread_model = .posix, + }, + .flags1 = .{ + .fp_op_fusion_mode = .standard, + .eabi_version = .default, + .debugger_kind = .default, + .exception_handling = .none, + }, + .loop_alignment = 0, + .mc = .{ + .abi_name = .{}, + .assembly_language = .{}, + .split_dwarf_file = .{}, + .as_secure_log_file = .{}, + .argv0 = null, + .argv_pointer = null, + .argv_count = 0, + .integrated_assembler_search_path_pointer = null, + .integrated_assembler_search_path_count = 0, + .flags = .{ + .relax_all = 0, + .no_exec_stack = 0, + .fatal_warnings = 0, + .no_warn = 0, + .no_deprecated_warn = 0, + .no_type_check = 0, + .save_temp_labels = 0, + .incremental_linker_compatible = 0, + .fdpic = 0, + .show_mc_encoding = 0, + .show_mc_inst = 0, + .asm_verbose = 0, + .preserve_asm_comments = 1, + .dwarf64 = 0, + .crel = 0, + .x86_relax_relocations = 0, + .x86_sse2_avx = 0, + .emit_dwarf_unwind = .default, + .use_dwarf_directory = .default, + .debug_compression_type = .none, + .emit_compact_unwind_non_canonical = 0, + .ppc_use_full_register_names = 0, + }, + }, + }, + .cpu_triple = String.from_slice(global.host_triple), + .cpu_model = String.from_slice(global.host_cpu_model), + .cpu_features = String.from_slice(global.host_cpu_features), + .optimization_level = .none, + .relocation_model = .default, + .code_model = .none, + .jit = false, + }, &error_message) orelse { + unreachable; + }; + _ = target_machine; } diff --git a/src/llvm.cpp b/src/llvm.cpp index 5ec99a9..360a768 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -160,6 +160,64 @@ EXPORT BBLLVMString llvm_host_cpu_features() return { result, length }; } +enum class BBLLVMEmitDwarfUnwindType : u8 +{ + always = 0, + no_compact_unwind = 1, + normal = 2, +}; + +enum class BBLLVMDwarfDirectory : u8 +{ + disable = 0, + enable = 1, + normal = 2, +}; + +enum class BBLLVMDebugCompressionType : u8 +{ + none = 0, + zlib = 1, + zstd = 2, +}; + +struct BBLLVMMCTargetOptions +{ + BBLLVMString abi_name; + BBLLVMString assembly_language; + BBLLVMString split_dwarf_file; + BBLLVMString as_secure_log_file; + const char* argv0; + BBLLVMString* argv_pointer; + u64 argv_count; + BBLLVMString* integrated_assembler_search_path_pointer; + u64 integrated_assembler_search_path_count; + u32 relax_all:1; + u32 no_exec_stack:1; + u32 fatal_warnings:1; + u32 no_warn:1; + u32 no_deprecated_warn:1; + u32 no_type_check:1; + u32 save_temp_labels:1; + u32 incremental_linker_compatible:1; + u32 fdpic:1; + u32 show_mc_encoding:1; + u32 show_mc_inst:1; + u32 asm_verbose:1; + u32 preserve_asm_comments:1; + u32 dwarf64:1; + u32 crel:1; + u32 x86_relax_relocations:1; + u32 x86_sse2_avx:1; + u32 emit_dwarf_unwind:2; + u32 use_dwarf_directory:2; + u32 debug_compression_type:2; + u32 emit_compact_unwind_non_canonical:1; + u32 ppc_use_full_register_names:1; + u32 reserved:7; +}; +static_assert(sizeof(BBLLVMMCTargetOptions) == 112); + enum class BBLLVMCodeModel : u8 { none = 0, @@ -189,446 +247,146 @@ enum class BBLLVMCodeGenerationOptimizationLevel : u8 aggressive = 3 // -O3 }; - // class TargetOptions { - // public: - // TargetOptions() - // : UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false), - // NoTrappingFPMath(true), NoSignedZerosFPMath(false), - // ApproxFuncFPMath(false), EnableAIXExtendedAltivecABI(false), - // HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false), - // GuaranteedTailCallOpt(false), StackSymbolOrdering(true), - // EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false), - // DisableIntegratedAS(false), FunctionSections(false), - // DataSections(false), IgnoreXCOFFVisibility(false), - // XCOFFTracebackTable(true), UniqueSectionNames(true), - // UniqueBasicBlockSectionNames(false), SeparateNamedSections(false), - // TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0), - // EmulatedTLS(false), EnableTLSDESC(false), EnableIPRA(false), - // EmitStackSizeSection(false), EnableMachineOutliner(false), - // EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false), - // EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false), - // SupportsDebugEntryValues(false), EnableDebugEntryValues(false), - // ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false), - // XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false), - // PPCGenScalarMASSEntries(false), JMCInstrument(false), - // EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false), - // FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {} - // - // /// DisableFramePointerElim - This returns true if frame pointer elimination - // /// optimization should be disabled for the given machine function. - // bool DisableFramePointerElim(const MachineFunction &MF) const; - // - // /// FramePointerIsReserved - This returns true if the frame pointer must - // /// always either point to a new frame record or be un-modified in the given - // /// function. - // bool FramePointerIsReserved(const MachineFunction &MF) const; - // - // /// If greater than 0, override the default value of - // /// MCAsmInfo::BinutilsVersion. - // std::pair BinutilsVersion{0, 0}; - // - // /// UnsafeFPMath - This flag is enabled when the - // /// -enable-unsafe-fp-math flag is specified on the command line. When - // /// this flag is off (the default), the code generator is not allowed to - // /// produce results that are "less precise" than IEEE allows. This includes - // /// use of X86 instructions like FSIN and FCOS instead of libcalls. - // unsigned UnsafeFPMath : 1; - // - // /// NoInfsFPMath - This flag is enabled when the - // /// -enable-no-infs-fp-math flag is specified on the command line. When - // /// this flag is off (the default), the code generator is not allowed to - // /// assume the FP arithmetic arguments and results are never +-Infs. - // unsigned NoInfsFPMath : 1; - // - // /// NoNaNsFPMath - This flag is enabled when the - // /// -enable-no-nans-fp-math flag is specified on the command line. When - // /// this flag is off (the default), the code generator is not allowed to - // /// assume the FP arithmetic arguments and results are never NaNs. - // unsigned NoNaNsFPMath : 1; - // - // /// NoTrappingFPMath - This flag is enabled when the - // /// -enable-no-trapping-fp-math is specified on the command line. This - // /// specifies that there are no trap handlers to handle exceptions. - // unsigned NoTrappingFPMath : 1; - // - // /// NoSignedZerosFPMath - This flag is enabled when the - // /// -enable-no-signed-zeros-fp-math is specified on the command line. This - // /// specifies that optimizations are allowed to treat the sign of a zero - // /// argument or result as insignificant. - // unsigned NoSignedZerosFPMath : 1; - // - // /// ApproxFuncFPMath - This flag is enabled when the - // /// -enable-approx-func-fp-math is specified on the command line. This - // /// specifies that optimizations are allowed to substitute math functions - // /// with approximate calculations - // unsigned ApproxFuncFPMath : 1; - // - // /// EnableAIXExtendedAltivecABI - This flag returns true when -vec-extabi is - // /// specified. The code generator is then able to use both volatile and - // /// nonvolitle vector registers. When false, the code generator only uses - // /// volatile vector registers which is the default setting on AIX. - // unsigned EnableAIXExtendedAltivecABI : 1; - // - // /// HonorSignDependentRoundingFPMath - This returns true when the - // /// -enable-sign-dependent-rounding-fp-math is specified. If this returns - // /// false (the default), the code generator is allowed to assume that the - // /// rounding behavior is the default (round-to-zero for all floating point - // /// to integer conversions, and round-to-nearest for all other arithmetic - // /// truncations). If this is enabled (set to true), the code generator must - // /// assume that the rounding mode may dynamically change. - // unsigned HonorSignDependentRoundingFPMathOption : 1; - // bool HonorSignDependentRoundingFPMath() const; - // - // /// NoZerosInBSS - By default some codegens place zero-initialized data to - // /// .bss section. This flag disables such behaviour (necessary, e.g. for - // /// crt*.o compiling). - // unsigned NoZerosInBSS : 1; - // - // /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is - // /// specified on the commandline. When the flag is on, participating targets - // /// will perform tail call optimization on all calls which use the fastcc - // /// calling convention and which satisfy certain target-independent - // /// criteria (being at the end of a function, having the same return type - // /// as their parent function, etc.), using an alternate ABI if necessary. - // unsigned GuaranteedTailCallOpt : 1; - // - // /// StackSymbolOrdering - When true, this will allow CodeGen to order - // /// the local stack symbols (for code size, code locality, or any other - // /// heuristics). When false, the local symbols are left in whatever order - // /// they were generated. Default is true. - // unsigned StackSymbolOrdering : 1; - // - // /// EnableFastISel - This flag enables fast-path instruction selection - // /// which trades away generated code quality in favor of reducing - // /// compile time. - // unsigned EnableFastISel : 1; - // - // /// EnableGlobalISel - This flag enables global instruction selection. - // unsigned EnableGlobalISel : 1; - // - // /// EnableGlobalISelAbort - Control abort behaviour when global instruction - // /// selection fails to lower/select an instruction. - // GlobalISelAbortMode GlobalISelAbort = GlobalISelAbortMode::Enable; - // - // /// Control when and how the Swift async frame pointer bit should - // /// be set. - // SwiftAsyncFramePointerMode SwiftAsyncFramePointer = - // SwiftAsyncFramePointerMode::Always; - // - // /// UseInitArray - Use .init_array instead of .ctors for static - // /// constructors. - // unsigned UseInitArray : 1; - // - // /// Disable the integrated assembler. - // unsigned DisableIntegratedAS : 1; - // - // /// Emit functions into separate sections. - // unsigned FunctionSections : 1; - // - // /// Emit data into separate sections. - // unsigned DataSections : 1; - // - // /// Do not emit visibility attribute for xcoff. - // unsigned IgnoreXCOFFVisibility : 1; - // - // /// Emit XCOFF traceback table. - // unsigned XCOFFTracebackTable : 1; - // - // unsigned UniqueSectionNames : 1; - // - // /// Use unique names for basic block sections. - // unsigned UniqueBasicBlockSectionNames : 1; - // - // /// Emit named sections with the same name into different sections. - // unsigned SeparateNamedSections : 1; - // - // /// Emit target-specific trap instruction for 'unreachable' IR instructions. - // unsigned TrapUnreachable : 1; - // - // /// Do not emit a trap instruction for 'unreachable' IR instructions behind - // /// noreturn calls, even if TrapUnreachable is true. - // unsigned NoTrapAfterNoreturn : 1; - // - // /// Bit size of immediate TLS offsets (0 == use the default). - // unsigned TLSSize : 8; - // - // /// EmulatedTLS - This flag enables emulated TLS model, using emutls - // /// function in the runtime library.. - // unsigned EmulatedTLS : 1; - // - // /// EnableTLSDESC - This flag enables TLS Descriptors. - // unsigned EnableTLSDESC : 1; - // - // /// This flag enables InterProcedural Register Allocation (IPRA). - // unsigned EnableIPRA : 1; - // - // /// Emit section containing metadata on function stack sizes. - // unsigned EmitStackSizeSection : 1; - // - // /// Enables the MachineOutliner pass. - // unsigned EnableMachineOutliner : 1; - // - // /// Enables the MachineFunctionSplitter pass. - // unsigned EnableMachineFunctionSplitter : 1; - // - // /// Set if the target supports default outlining behaviour. - // unsigned SupportsDefaultOutlining : 1; - // - // /// Emit address-significance table. - // unsigned EmitAddrsig : 1; - // - // // Emit the SHT_LLVM_BB_ADDR_MAP section containing basic block address - // // which can be used to map virtual addresses to machine basic blocks. - // unsigned BBAddrMap : 1; - // - // /// Emit basic blocks into separate sections. - // BasicBlockSection BBSections = BasicBlockSection::None; - // - // /// Memory Buffer that contains information on sampled basic blocks and used - // /// to selectively generate basic block sections. - // std::shared_ptr BBSectionsFuncListBuf; - // - // /// The flag enables call site info production. It is used only for debug - // /// info, and it is restricted only to optimized code. This can be used for - // /// something else, so that should be controlled in the frontend. - // unsigned EmitCallSiteInfo : 1; - // /// Set if the target supports the debug entry values by default. - // unsigned SupportsDebugEntryValues : 1; - // /// When set to true, the EnableDebugEntryValues option forces production - // /// of debug entry values even if the target does not officially support - // /// it. Useful for testing purposes only. This flag should never be checked - // /// directly, always use \ref ShouldEmitDebugEntryValues instead. - // unsigned EnableDebugEntryValues : 1; - // /// NOTE: There are targets that still do not support the debug entry values - // /// production. - // bool ShouldEmitDebugEntryValues() const; - // - // // When set to true, use experimental new debug variable location tracking, - // // which seeks to follow the values of variables rather than their location, - // // post isel. - // unsigned ValueTrackingVariableLocations : 1; - // - // /// Emit DWARF debug frame section. - // unsigned ForceDwarfFrameSection : 1; - // - // /// Emit XRay Function Index section - // unsigned XRayFunctionIndex : 1; - // - // /// When set to true, don't use DWARF extensions in later DWARF versions. - // /// By default, it is set to false. - // unsigned DebugStrictDwarf : 1; - // - // /// Emit the hotpatch flag in CodeView debug. - // unsigned Hotpatch : 1; - // - // /// Enables scalar MASS conversions - // unsigned PPCGenScalarMASSEntries : 1; - // - // /// Enable JustMyCode instrumentation. - // unsigned JMCInstrument : 1; - // - // /// Enable the CFIFixup pass. - // unsigned EnableCFIFixup : 1; - // - // /// When set to true, enable MisExpect Diagnostics - // /// By default, it is set to false - // unsigned MisExpect : 1; - // - // /// When set to true, const objects with relocatable address values are put - // /// into the RO data section. - // unsigned XCOFFReadOnlyPointers : 1; - // - // /// Name of the stack usage file (i.e., .su file) if user passes - // /// -fstack-usage. If empty, it can be implied that -fstack-usage is not - // /// passed on the command line. - // std::string StackUsageOutput; - // - // /// If greater than 0, override TargetLoweringBase::PrefLoopAlignment. - // unsigned LoopAlignment = 0; - // - // /// FloatABIType - This setting is set by -float-abi=xxx option is specfied - // /// on the command line. This setting may either be Default, Soft, or Hard. - // /// Default selects the target's default behavior. Soft selects the ABI for - // /// software floating point, but does not indicate that FP hardware may not - // /// be used. Such a combination is unfortunately popular (e.g. - // /// arm-apple-darwin). Hard presumes that the normal FP ABI is used. - // FloatABI::ABIType FloatABIType = FloatABI::Default; - // - // /// AllowFPOpFusion - This flag is set by the -fp-contract=xxx option. - // /// This controls the creation of fused FP ops that store intermediate - // /// results in higher precision than IEEE allows (E.g. FMAs). - // /// - // /// Fast mode - allows formation of fused FP ops whenever they're - // /// profitable. - // /// Standard mode - allow fusion only for 'blessed' FP ops. At present the - // /// only blessed op is the fmuladd intrinsic. In the future more blessed ops - // /// may be added. - // /// Strict mode - allow fusion only if/when it can be proven that the excess - // /// precision won't effect the result. - // /// - // /// Note: This option only controls formation of fused ops by the - // /// optimizers. Fused operations that are explicitly specified (e.g. FMA - // /// via the llvm.fma.* intrinsic) will always be honored, regardless of - // /// the value of this option. - // FPOpFusion::FPOpFusionMode AllowFPOpFusion = FPOpFusion::Standard; - // - // /// ThreadModel - This flag specifies the type of threading model to assume - // /// for things like atomics - // ThreadModel::Model ThreadModel = ThreadModel::POSIX; - // - // /// EABIVersion - This flag specifies the EABI version - // EABI EABIVersion = EABI::Default; - // - // /// Which debugger to tune for. - // DebuggerKind DebuggerTuning = DebuggerKind::Default; - // - // private: - // /// Flushing mode to assume in default FP environment. - // DenormalMode FPDenormalMode; - // - // /// Flushing mode to assume in default FP environment, for float/vector of - // /// float. - // DenormalMode FP32DenormalMode; - // - // public: - // void setFPDenormalMode(DenormalMode Mode) { - // FPDenormalMode = Mode; - // } - // - // void setFP32DenormalMode(DenormalMode Mode) { - // FP32DenormalMode = Mode; - // } - // - // DenormalMode getRawFPDenormalMode() const { - // return FPDenormalMode; - // } - // - // DenormalMode getRawFP32DenormalMode() const { - // return FP32DenormalMode; - // } - // - // DenormalMode getDenormalMode(const fltSemantics &FPType) const; - // - // /// What exception model to use - // ExceptionHandling ExceptionModel = ExceptionHandling::None; - // - // /// Machine level options. - // MCTargetOptions MCOptions; - // - // /// Stores the filename/path of the final .o/.obj file, to be written in the - // /// debug information. This is used for emitting the CodeView S_OBJNAME - // /// record. - // std::string ObjectFilenameForDebug; - // }; - // namespace FloatABI { - // enum ABIType { - // Default, // Target-specific (either soft or hard depending on triple, etc). - // Soft, // Soft float. - // Hard // Hard float. - // }; - // } - // - // namespace FPOpFusion { - // enum FPOpFusionMode { - // Fast, // Enable fusion of FP ops wherever it's profitable. - // Standard, // Only allow fusion of 'blessed' ops (currently just fmuladd). - // Strict // Never fuse FP-ops. - // }; - // } - // - // namespace JumpTable { - // enum JumpTableType { - // Single, // Use a single table for all indirect jumptable calls. - // Arity, // Use one table per number of function parameters. - // Simplified, // Use one table per function type, with types projected - // // into 4 types: pointer to non-function, struct, - // // primitive, and function pointer. - // Full // Use one table per unique function type - // }; - // } - // - // namespace ThreadModel { - // enum Model { - // POSIX, // POSIX Threads - // Single // Single Threaded Environment - // }; - // } - // - // enum class BasicBlockSection { - // All, // Use Basic Block Sections for all basic blocks. A section - // // for every basic block can significantly bloat object file sizes. - // List, // Get list of functions & BBs from a file. Selectively enables - // // basic block sections for a subset of basic blocks which can be - // // used to control object size bloats from creating sections. - // Labels, // Do not use Basic Block Sections but label basic blocks. This - // // is useful when associating profile counts from virtual addresses - // // to basic blocks. - // Preset, // Similar to list but the blocks are identified by passes which - // // seek to use Basic Block Sections, e.g. MachineFunctionSplitter. - // // This option cannot be set via the command line. - // None // Do not use Basic Block Sections. - // }; - // - // enum class EABI { - // Unknown, - // Default, // Default means not specified - // EABI4, // Target-specific (either 4, 5 or gnu depending on triple). - // EABI5, - // GNU - // }; - // - // /// Identify a debugger for "tuning" the debug info. - // /// - // /// The "debugger tuning" concept allows us to present a more intuitive - // /// interface that unpacks into different sets of defaults for the various - // /// individual feature-flag settings, that suit the preferences of the - // /// various debuggers. However, it's worth remembering that debuggers are - // /// not the only consumers of debug info, and some variations in DWARF might - // /// better be treated as target/platform issues. Fundamentally, - // /// o if the feature is useful (or not) to a particular debugger, regardless - // /// of the target, that's a tuning decision; - // /// o if the feature is useful (or not) on a particular platform, regardless - // /// of the debugger, that's a target decision. - // /// It's not impossible to see both factors in some specific case. - // enum class DebuggerKind { - // Default, ///< No specific tuning requested. - // GDB, ///< Tune debug info for gdb. - // LLDB, ///< Tune debug info for lldb. - // SCE, ///< Tune debug info for SCE targets (e.g. PS4). - // DBX ///< Tune debug info for dbx. - // }; - // - // /// Enable abort calls when global instruction selection fails to lower/select - // /// an instruction. - // enum class GlobalISelAbortMode { - // Disable, // Disable the abort. - // Enable, // Enable the abort. - // DisableWithDiag // Disable the abort but emit a diagnostic on failure. - // }; - // - // /// Indicates when and how the Swift async frame pointer bit should be set. - // enum class SwiftAsyncFramePointerMode { - // /// Determine whether to set the bit statically or dynamically based - // /// on the deployment target. - // DeploymentBased, - // /// Always set the bit. - // Always, - // /// Never set the bit. - // Never, - // }; - // - // /// \brief Enumeration value for AMDGPU code object version, which is the - // /// code object version times 100. - // enum CodeObjectVersionKind { - // COV_None, - // COV_2 = 200, // Unsupported. - // COV_3 = 300, // Unsupported. - // COV_4 = 400, - // COV_5 = 500, - // COV_6 = 600, - // }; +enum class BBLLVMGlobalISelAbortMode : u8 +{ + disable = 0, + enable = 1, + disable_with_diag = 2, +}; + +enum class BBLLVMSwiftAsyncFramePointerMode : u8 +{ + deployment_based = 0, + always = 1, + never = 2, +}; + +enum class BBLLVMBasicBlockSection : u8 +{ + all = 0, + list = 1, + labels = 2, + preset = 3, + none = 4, +}; + +enum class BBLLVMFloatAbi : u8 +{ + normal = 0, + soft = 1, + hard = 2, +}; + +enum class BBLLVMFPOpFusion : u8 +{ + fast = 0, + standard = 1, + strict = 2, +}; + +enum class BBLLVMThreadModel : u8 +{ + posix = 0, + single = 1, +}; + +enum class BBLLVMEAbi : u8 +{ + unknown = 0, + normal = 1, + eabi4 = 2, + eabi5 = 3, + gnu = 4, +}; + +enum class BBLLVMDebuggerKind : u8 +{ + normal = 0, + gdb = 1, + lldb = 2, + sce = 3, + dbx = 4, +}; + +enum class BBLLVMExceptionHandling : u8 +{ + none = 0, + dwarf_cfi = 1, + setjmp_longjmp = 2, + arm = 3, + win_eh = 4, + wasm = 5, + aix = 6, + zos = 7, +}; + struct BBLLVMTargetOptions { + u64 unsafe_fp_math:1; + u64 no_infs_fp_math:1; + u64 no_nans_fp_math:1; + u64 no_trapping_fp_math:1; + u64 no_signed_zeroes_fp_math:1; + u64 approx_func_fp_match:1; + u64 enable_aix_extended_altivec_abi:1; + u64 honor_sign_dependent_rounding_fp_math:1; + u64 no_zeroes_in_bss:1; + u64 guaranteed_tail_call_optimization:1; + u64 stack_symbol_ordering:1; + u64 enable_fast_isel:1; + u64 enable_global_isel:1; + u64 global_isel_abort_mode:2; + u64 swift_async_frame_pointer:2; + u64 use_init_array:1; + u64 disabled_integrated_assembler:1; + u64 function_sections:1; + u64 data_sections:1; + u64 ignore_xcoff_visibility:1; + u64 xcoff_traceback_table:1; + u64 unique_section_names:1; + u64 unique_basic_block_section_names:1; + u64 separate_named_sections:1; + u64 trap_unreachable:1; + u64 no_trap_after_noreturn:1; + u64 tls_size:8; + u64 emulated_tls:1; + u64 enable_tls_descriptors:1; + u64 enable_ipra:1; + u64 emit_stack_size_section:1; + u64 enable_machine_outliner:1; + u64 enable_machine_function_splitter:1; + u64 supports_default_outlining:1; + u64 emit_address_significance_table:1; + u64 bb_address_map:1; + u64 bb_sections:3; + u64 emit_call_site_information:1; + u64 supports_debug_entry_values:1; + u64 enable_debug_entry_values:1; + u64 value_tracking_variable_locations:1; + u64 force_dwarf_frame_section:1; + u64 xray_function_index:1; + u64 debug_strict_dwarf:1; + u64 hotpatch:1; + u64 ppc_gen_scalar_mass_entries:1; + u64 jmc_instrument:1; + u64 enable_cfi_fixup:1; + u64 mis_expect:1; + u64 xcoff_read_only_pointers:1; + u64 float_abi:2; + u64 thread_model:1; + u32 fp_op_fusion_mode:2; + u32 eabi_version:3; + u32 debugger_kind:3; + u32 exception_handling:3; + u32 reserved:21; + unsigned loop_alignment; + struct + { + int major; + int minor; + } binutils_version; + + BBLLVMMCTargetOptions mc; }; struct BBLLVMTargetMachineCreate @@ -644,6 +402,8 @@ struct BBLLVMTargetMachineCreate u32 reserved; }; +static_assert(sizeof(BBLLVMTargetMachineCreate) == 192); + EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate& create, BBLLVMString* error_message) { std::string error_message_string; @@ -700,4 +460,3 @@ EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate return target_machine; } - diff --git a/src/llvm_api.zig b/src/llvm_api.zig index 38ad14c..7b0965f 100644 --- a/src/llvm_api.zig +++ b/src/llvm_api.zig @@ -71,6 +71,8 @@ pub extern fn llvm_default_target_triple() llvm.String; pub extern fn llvm_host_cpu_name() llvm.String; pub extern fn llvm_host_cpu_features() llvm.String; +pub extern fn llvm_create_target_machine(create: *const llvm.Target.Machine.Create, error_message: *llvm.String) ?*llvm.Target.Machine; + pub fn get_initializer(comptime llvm_arch: llvm.Architecture) type { const arch_name = @tagName(llvm_arch); return struct {