aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig12
-rw-r--r--src/codegen/llvm.zig9
-rw-r--r--src/codegen/llvm/bindings.zig8
3 files changed, 29 insertions, 0 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index ff49b18f7b..a2e2d7b20d 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -842,6 +842,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM
.breakpoint => try airBreakpoint(o),
.unreach => try airUnreach(o),
+ .fence => try airFence(o, inst),
// TODO use a different strategy for add that communicates to the optimizer
// that wrapping is UB.
@@ -1439,6 +1440,17 @@ fn airBreakpoint(o: *Object) !CValue {
return CValue.none;
}
+fn airFence(o: *Object, inst: Air.Inst.Index) !CValue {
+ const atomic_order = o.air.instructions.items(.data)[inst].fence;
+ const writer = o.writer();
+
+ try writer.writeAll("zig_fence(");
+ try writeMemoryOrder(writer, atomic_order);
+ try writer.writeAll(");\n");
+
+ return CValue.none;
+}
+
fn airUnreach(o: *Object) !CValue {
try o.writer().writeAll("zig_unreachable();\n");
return CValue.none;
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index b28c371466..569f857caa 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1059,6 +1059,7 @@ pub const FuncGen = struct {
.array_to_slice => try self.airArrayToSlice(inst),
.cmpxchg_weak => try self.airCmpxchg(inst, true),
.cmpxchg_strong => try self.airCmpxchg(inst, false),
+ .fence => try self.airFence(inst),
.struct_field_ptr => try self.airStructFieldPtr(inst),
.struct_field_val => try self.airStructFieldVal(inst),
@@ -2005,6 +2006,14 @@ pub const FuncGen = struct {
return null;
}
+ fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
+ const atomic_order = self.air.instructions.items(.data)[inst].fence;
+ const llvm_memory_order = toLlvmAtomicOrdering(atomic_order);
+ const single_threaded = llvm.Bool.fromBool(self.single_threaded);
+ _ = self.builder.buildFence(llvm_memory_order, single_threaded, "");
+ return null;
+ }
+
fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*const llvm.Value {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
index b4bd91708d..3fed3ca879 100644
--- a/src/codegen/llvm/bindings.zig
+++ b/src/codegen/llvm/bindings.zig
@@ -522,6 +522,14 @@ pub const Builder = opaque {
Else: *const Value,
Name: [*:0]const u8,
) *const Value;
+
+ pub const buildFence = LLVMBuildFence;
+ extern fn LLVMBuildFence(
+ B: *const Builder,
+ ordering: AtomicOrdering,
+ singleThread: Bool,
+ Name: [*:0]const u8,
+ ) *const Value;
};
pub const IntPredicate = enum(c_uint) {