diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 27092a1de89c9801bd8dab398fc4f50e9cc49c57..db628eab5dacf291bd6a4f101eea1d85b0ef640c 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1047,6 +1047,7 @@ pub const Object = struct { comp.data_sections, float_abi, if (target_util.llvmMachineAbi(&comp.root_mod.resolved_target.result)) |s| s.ptr else null, + target_util.useEmulatedTls(&comp.root_mod.resolved_target.result), ); errdefer target_machine.dispose(); diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 5d2d4c2a99304911809d9677a0e2e8667b97b19c..7fa2a7da4356ec55c1e61cf11aedb12ef3cb44ee 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -79,6 +79,7 @@ pub const TargetMachine = opaque { data_sections: bool, float_abi: FloatABI, abi_name: ?[*:0]const u8, + emulated_tls: bool, ) *TargetMachine; pub const dispose = LLVMDisposeTargetMachine; diff --git a/src/main.zig b/src/main.zig index 7b7d5be59ae09a88d33e2f2c648efa25d05bfe16..aa20b8fae1b26a2486671181a9eab21e79a4b242 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6324,7 +6324,7 @@ fn cmdDumpLlvmInts( if (llvm.Target.getFromTriple(triple, &target, &error_message) != .False) @panic("bad"); break :t target; }; - const tm = llvm.TargetMachine.create(target, triple, null, null, .None, .Default, .Default, false, false, .Default, null); + const tm = llvm.TargetMachine.create(target, triple, null, null, .None, .Default, .Default, false, false, .Default, null, false); const dl = tm.createTargetDataLayout(); const context = llvm.Context.create(); diff --git a/src/target.zig b/src/target.zig index 28cdf3e3aab1f6c911ac4d4bd8b0bb0e2dd2719f..7852dda7a4386bff4e1e961b36aa8d76084e1a5e 100644 --- a/src/target.zig +++ b/src/target.zig @@ -85,6 +85,19 @@ pub fn defaultSingleThreaded(target: *const std.Target) bool { return false; } +pub fn useEmulatedTls(target: *const std.Target) bool { + if (target.abi.isAndroid()) { + if (target.os.version_range.linux.android < 29) return true; + return false; + } + if (target.abi.isOpenHarmony()) return true; + return switch (target.os.tag) { + .openbsd => true, + .windows => target.abi == .cygnus, + else => false, + }; +} + pub fn hasValgrindSupport(target: *const std.Target, backend: std.builtin.CompilerBackend) bool { // We can't currently output the necessary Valgrind client request assembly when using the C // backend and compiling with an MSVC-like compiler. diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index fe4e421dc3238380cc5c159506074cfcefd5c39c..c9a30bb167e5319f944f998fd8a8991c1b98ad46 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -83,7 +83,7 @@ static const bool assertions_on = false; LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel, bool function_sections, bool data_sections, ZigLLVMFloatABI float_abi, - const char *abi_name) + const char *abi_name, bool emulated_tls) { std::optional RM; switch (Reloc){ @@ -149,6 +149,10 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri opt.MCOptions.ABIName = abi_name; } + if (emulated_tls) { + opt.EmulatedTLS = true; + } + TargetMachine *TM = reinterpret_cast(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, OL, JIT); return reinterpret_cast(TM); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index e2dba338c3af31aa89d4255c2dd8f266a1d64ee5..db331512bd908d7e7e73b50d097314a617726153 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -105,7 +105,7 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel, bool function_sections, bool data_sections, ZigLLVMFloatABI float_abi, - const char *abi_name); + const char *abi_name, bool emulated_tls); ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit);