aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-08-07 09:35:38 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2023-08-08 21:32:50 -0400
commita0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db (patch)
treeb7bac1f57b40c2f53e86fd8a2183c11add1a7d9c /src/codegen/llvm.zig
parent49cc1bff086e9c521c110b35692a87f75e25c7ad (diff)
downloadzig-a0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db.tar.gz
zig-a0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db.zip
llvm: finish converting instructions
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig148
1 files changed, 70 insertions, 78 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 47cfe58904..3684237cb2 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -4911,8 +4911,8 @@ pub const FuncGen = struct {
.array_to_slice => try self.airArrayToSlice(inst),
.float_from_int => try self.airFloatFromInt(inst),
- .cmpxchg_weak => try self.airCmpxchg(inst, true),
- .cmpxchg_strong => try self.airCmpxchg(inst, false),
+ .cmpxchg_weak => try self.airCmpxchg(inst, .weak),
+ .cmpxchg_strong => try self.airCmpxchg(inst, .strong),
.fence => try self.airFence(inst),
.atomic_rmw => try self.airAtomicRmw(inst),
.atomic_load => try self.airAtomicLoad(inst),
@@ -8723,15 +8723,20 @@ pub const FuncGen = struct {
return .none;
}
- fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !Builder.Value {
+ fn airCmpxchg(
+ self: *FuncGen,
+ inst: Air.Inst.Index,
+ kind: Builder.Function.Instruction.CmpXchg.Kind,
+ ) !Builder.Value {
const o = self.dg.object;
const mod = o.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
const ptr = try self.resolveInst(extra.ptr);
+ const ptr_ty = self.typeOf(extra.ptr);
var expected_value = try self.resolveInst(extra.expected_value);
var new_value = try self.resolveInst(extra.new_value);
- const operand_ty = self.typeOf(extra.ptr).childType(mod);
+ const operand_ty = ptr_ty.childType(mod);
const llvm_operand_ty = try o.lowerType(operand_ty);
const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);
if (llvm_abi_ty != .none) {
@@ -8742,22 +8747,18 @@ pub const FuncGen = struct {
new_value = try self.wip.conv(signedness, new_value, llvm_abi_ty, "");
}
- const llvm_result_ty = try o.builder.structType(.normal, &.{
- if (llvm_abi_ty != .none) llvm_abi_ty else llvm_operand_ty,
- .i1,
- });
- const result = (try self.wip.unimplemented(llvm_result_ty, "")).finish(
- self.builder.buildAtomicCmpXchg(
- ptr.toLlvm(&self.wip),
- expected_value.toLlvm(&self.wip),
- new_value.toLlvm(&self.wip),
- @enumFromInt(@intFromEnum(toLlvmAtomicOrdering(extra.successOrder()))),
- @enumFromInt(@intFromEnum(toLlvmAtomicOrdering(extra.failureOrder()))),
- llvm.Bool.fromBool(self.sync_scope == .singlethread),
- ),
- &self.wip,
+ const result = try self.wip.cmpxchg(
+ kind,
+ if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
+ ptr,
+ expected_value,
+ new_value,
+ self.sync_scope,
+ toLlvmAtomicOrdering(extra.successOrder()),
+ toLlvmAtomicOrdering(extra.failureOrder()),
+ Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod)),
+ "",
);
- result.toLlvm(&self.wip).setWeak(llvm.Bool.fromBool(is_weak));
const optional_ty = self.typeOfIndex(inst);
@@ -8789,63 +8790,54 @@ pub const FuncGen = struct {
const is_float = operand_ty.isRuntimeFloat();
const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
const ordering = toLlvmAtomicOrdering(extra.ordering());
- const single_threaded = llvm.Bool.fromBool(self.sync_scope == .singlethread);
- const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, op == .Xchg);
+ const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, op == .xchg);
const llvm_operand_ty = try o.lowerType(operand_ty);
+
+ const access_kind: Builder.MemoryAccessKind =
+ if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
+ const ptr_alignment = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));
+
if (llvm_abi_ty != .none) {
// operand needs widening and truncating or bitcasting.
- const casted_operand = try self.wip.cast(
- if (is_float) .bitcast else if (is_signed_int) .sext else .zext,
- @enumFromInt(@intFromEnum(operand)),
- llvm_abi_ty,
- "",
- );
-
- const uncasted_result = (try self.wip.unimplemented(llvm_abi_ty, "")).finish(
- self.builder.buildAtomicRmw(
- op,
- ptr.toLlvm(&self.wip),
- casted_operand.toLlvm(&self.wip),
- @enumFromInt(@intFromEnum(ordering)),
- single_threaded,
+ return self.wip.cast(if (is_float) .bitcast else .trunc, try self.wip.atomicrmw(
+ access_kind,
+ op,
+ ptr,
+ try self.wip.cast(
+ if (is_float) .bitcast else if (is_signed_int) .sext else .zext,
+ operand,
+ llvm_abi_ty,
+ "",
),
- &self.wip,
- );
-
- if (is_float) {
- return self.wip.cast(.bitcast, uncasted_result, llvm_operand_ty, "");
- } else {
- return self.wip.cast(.trunc, uncasted_result, llvm_operand_ty, "");
- }
+ self.sync_scope,
+ ordering,
+ ptr_alignment,
+ "",
+ ), llvm_operand_ty, "");
}
- if (!llvm_operand_ty.isPointer(&o.builder)) {
- return (try self.wip.unimplemented(llvm_operand_ty, "")).finish(
- self.builder.buildAtomicRmw(
- op,
- ptr.toLlvm(&self.wip),
- operand.toLlvm(&self.wip),
- @enumFromInt(@intFromEnum(ordering)),
- single_threaded,
- ),
- &self.wip,
- );
- }
+ if (!llvm_operand_ty.isPointer(&o.builder)) return self.wip.atomicrmw(
+ access_kind,
+ op,
+ ptr,
+ operand,
+ self.sync_scope,
+ ordering,
+ ptr_alignment,
+ "",
+ );
// It's a pointer but we need to treat it as an int.
- const llvm_usize = try o.lowerType(Type.usize);
- const casted_operand = try self.wip.cast(.ptrtoint, operand, llvm_usize, "");
- const uncasted_result = (try self.wip.unimplemented(llvm_usize, "")).finish(
- self.builder.buildAtomicRmw(
- op,
- ptr.toLlvm(&self.wip),
- casted_operand.toLlvm(&self.wip),
- @enumFromInt(@intFromEnum(ordering)),
- single_threaded,
- ),
- &self.wip,
- );
- return self.wip.cast(.inttoptr, uncasted_result, llvm_operand_ty, "");
+ return self.wip.cast(.inttoptr, try self.wip.atomicrmw(
+ access_kind,
+ op,
+ ptr,
+ try self.wip.cast(.ptrtoint, operand, try o.lowerType(Type.usize), ""),
+ self.sync_scope,
+ ordering,
+ ptr_alignment,
+ "",
+ ), llvm_operand_ty, "");
}
fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
@@ -10581,17 +10573,17 @@ fn toLlvmAtomicRmwBinOp(
op: std.builtin.AtomicRmwOp,
is_signed: bool,
is_float: bool,
-) llvm.AtomicRMWBinOp {
+) Builder.Function.Instruction.AtomicRmw.Operation {
return switch (op) {
- .Xchg => .Xchg,
- .Add => if (is_float) .FAdd else return .Add,
- .Sub => if (is_float) .FSub else return .Sub,
- .And => .And,
- .Nand => .Nand,
- .Or => .Or,
- .Xor => .Xor,
- .Max => if (is_float) .FMax else if (is_signed) .Max else return .UMax,
- .Min => if (is_float) .FMin else if (is_signed) .Min else return .UMin,
+ .Xchg => .xchg,
+ .Add => if (is_float) .fadd else return .add,
+ .Sub => if (is_float) .fsub else return .sub,
+ .And => .@"and",
+ .Nand => .nand,
+ .Or => .@"or",
+ .Xor => .xor,
+ .Max => if (is_float) .fmax else if (is_signed) .max else return .umax,
+ .Min => if (is_float) .fmin else if (is_signed) .min else return .umin,
};
}