diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-08-07 09:35:38 -0400 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-08-08 21:32:50 -0400 |
| commit | a0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db (patch) | |
| tree | b7bac1f57b40c2f53e86fd8a2183c11add1a7d9c /src/codegen/llvm.zig | |
| parent | 49cc1bff086e9c521c110b35692a87f75e25c7ad (diff) | |
| download | zig-a0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db.tar.gz zig-a0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db.zip | |
llvm: finish converting instructions
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 148 |
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, }; } |
