authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-07 09:35:38-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-08 21:32:50-04:00
loga0cb03ed99d0e157389d8afad4ab4f9c8e8ea2db
treeb7bac1f57b40c2f53e86fd8a2183c11add1a7d9c
parent49cc1bff086e9c521c110b35692a87f75e25c7ad

llvm: finish converting instructions


4 files changed, 364 insertions(+), 217 deletions(-)

src/codegen/llvm.zig+70-78
...@@ -4911,8 +4911,8 @@ pub const FuncGen = struct {...@@ -4911,8 +4911,8 @@ pub const FuncGen = struct {
49114911
4912 .array_to_slice => try self.airArrayToSlice(inst),4912 .array_to_slice => try self.airArrayToSlice(inst),
4913 .float_from_int => try self.airFloatFromInt(inst),4913 .float_from_int => try self.airFloatFromInt(inst),
4914 .cmpxchg_weak => try self.airCmpxchg(inst, true),4914 .cmpxchg_weak => try self.airCmpxchg(inst, .weak),
4915 .cmpxchg_strong => try self.airCmpxchg(inst, false),4915 .cmpxchg_strong => try self.airCmpxchg(inst, .strong),
4916 .fence => try self.airFence(inst),4916 .fence => try self.airFence(inst),
4917 .atomic_rmw => try self.airAtomicRmw(inst),4917 .atomic_rmw => try self.airAtomicRmw(inst),
4918 .atomic_load => try self.airAtomicLoad(inst),4918 .atomic_load => try self.airAtomicLoad(inst),
...@@ -8723,15 +8723,20 @@ pub const FuncGen = struct {...@@ -8723,15 +8723,20 @@ pub const FuncGen = struct {
8723 return .none;8723 return .none;
8724 }8724 }
87258725
8726 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !Builder.Value {8726 fn airCmpxchg(
8727 self: *FuncGen,
8728 inst: Air.Inst.Index,
8729 kind: Builder.Function.Instruction.CmpXchg.Kind,
8730 ) !Builder.Value {
8727 const o = self.dg.object;8731 const o = self.dg.object;
8728 const mod = o.module;8732 const mod = o.module;
8729 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8733 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8730 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;8734 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
8731 const ptr = try self.resolveInst(extra.ptr);8735 const ptr = try self.resolveInst(extra.ptr);
8736 const ptr_ty = self.typeOf(extra.ptr);
8732 var expected_value = try self.resolveInst(extra.expected_value);8737 var expected_value = try self.resolveInst(extra.expected_value);
8733 var new_value = try self.resolveInst(extra.new_value);8738 var new_value = try self.resolveInst(extra.new_value);
8734 const operand_ty = self.typeOf(extra.ptr).childType(mod);8739 const operand_ty = ptr_ty.childType(mod);
8735 const llvm_operand_ty = try o.lowerType(operand_ty);8740 const llvm_operand_ty = try o.lowerType(operand_ty);
8736 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);8741 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, false);
8737 if (llvm_abi_ty != .none) {8742 if (llvm_abi_ty != .none) {
...@@ -8742,22 +8747,18 @@ pub const FuncGen = struct {...@@ -8742,22 +8747,18 @@ pub const FuncGen = struct {
8742 new_value = try self.wip.conv(signedness, new_value, llvm_abi_ty, "");8747 new_value = try self.wip.conv(signedness, new_value, llvm_abi_ty, "");
8743 }8748 }
87448749
8745 const llvm_result_ty = try o.builder.structType(.normal, &.{8750 const result = try self.wip.cmpxchg(
8746 if (llvm_abi_ty != .none) llvm_abi_ty else llvm_operand_ty,8751 kind,
8747 .i1,8752 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
8748 });8753 ptr,
8749 const result = (try self.wip.unimplemented(llvm_result_ty, "")).finish(8754 expected_value,
8750 self.builder.buildAtomicCmpXchg(8755 new_value,
8751 ptr.toLlvm(&self.wip),8756 self.sync_scope,
8752 expected_value.toLlvm(&self.wip),8757 toLlvmAtomicOrdering(extra.successOrder()),
8753 new_value.toLlvm(&self.wip),8758 toLlvmAtomicOrdering(extra.failureOrder()),
8754 @enumFromInt(@intFromEnum(toLlvmAtomicOrdering(extra.successOrder()))),8759 Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod)),
8755 @enumFromInt(@intFromEnum(toLlvmAtomicOrdering(extra.failureOrder()))),8760 "",
8756 llvm.Bool.fromBool(self.sync_scope == .singlethread),
8757 ),
8758 &self.wip,
8759 );8761 );
8760 result.toLlvm(&self.wip).setWeak(llvm.Bool.fromBool(is_weak));
87618762
8762 const optional_ty = self.typeOfIndex(inst);8763 const optional_ty = self.typeOfIndex(inst);
87638764
...@@ -8789,63 +8790,54 @@ pub const FuncGen = struct {...@@ -8789,63 +8790,54 @@ pub const FuncGen = struct {
8789 const is_float = operand_ty.isRuntimeFloat();8790 const is_float = operand_ty.isRuntimeFloat();
8790 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);8791 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
8791 const ordering = toLlvmAtomicOrdering(extra.ordering());8792 const ordering = toLlvmAtomicOrdering(extra.ordering());
8792 const single_threaded = llvm.Bool.fromBool(self.sync_scope == .singlethread);8793 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, op == .xchg);
8793 const llvm_abi_ty = try o.getAtomicAbiType(operand_ty, op == .Xchg);
8794 const llvm_operand_ty = try o.lowerType(operand_ty);8794 const llvm_operand_ty = try o.lowerType(operand_ty);
8795
8796 const access_kind: Builder.MemoryAccessKind =
8797 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
8798 const ptr_alignment = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));
8799
8795 if (llvm_abi_ty != .none) {8800 if (llvm_abi_ty != .none) {
8796 // operand needs widening and truncating or bitcasting.8801 // operand needs widening and truncating or bitcasting.
8797 const casted_operand = try self.wip.cast(8802 return self.wip.cast(if (is_float) .bitcast else .trunc, try self.wip.atomicrmw(
8798 if (is_float) .bitcast else if (is_signed_int) .sext else .zext,8803 access_kind,
8799 @enumFromInt(@intFromEnum(operand)),8804 op,
8800 llvm_abi_ty,8805 ptr,
8801 "",8806 try self.wip.cast(
8802 );8807 if (is_float) .bitcast else if (is_signed_int) .sext else .zext,
88038808 operand,
8804 const uncasted_result = (try self.wip.unimplemented(llvm_abi_ty, "")).finish(8809 llvm_abi_ty,
8805 self.builder.buildAtomicRmw(8810 "",
8806 op,
8807 ptr.toLlvm(&self.wip),
8808 casted_operand.toLlvm(&self.wip),
8809 @enumFromInt(@intFromEnum(ordering)),
8810 single_threaded,
8811 ),8811 ),
8812 &self.wip,8812 self.sync_scope,
8813 );8813 ordering,
88148814 ptr_alignment,
8815 if (is_float) {8815 "",
8816 return self.wip.cast(.bitcast, uncasted_result, llvm_operand_ty, "");8816 ), llvm_operand_ty, "");
8817 } else {
8818 return self.wip.cast(.trunc, uncasted_result, llvm_operand_ty, "");
8819 }
8820 }8817 }
88218818
8822 if (!llvm_operand_ty.isPointer(&o.builder)) {8819 if (!llvm_operand_ty.isPointer(&o.builder)) return self.wip.atomicrmw(
8823 return (try self.wip.unimplemented(llvm_operand_ty, "")).finish(8820 access_kind,
8824 self.builder.buildAtomicRmw(8821 op,
8825 op,8822 ptr,
8826 ptr.toLlvm(&self.wip),8823 operand,
8827 operand.toLlvm(&self.wip),8824 self.sync_scope,
8828 @enumFromInt(@intFromEnum(ordering)),8825 ordering,
8829 single_threaded,8826 ptr_alignment,
8830 ),8827 "",
8831 &self.wip,8828 );
8832 );
8833 }
88348829
8835 // It's a pointer but we need to treat it as an int.8830 // It's a pointer but we need to treat it as an int.
8836 const llvm_usize = try o.lowerType(Type.usize);8831 return self.wip.cast(.inttoptr, try self.wip.atomicrmw(
8837 const casted_operand = try self.wip.cast(.ptrtoint, operand, llvm_usize, "");8832 access_kind,
8838 const uncasted_result = (try self.wip.unimplemented(llvm_usize, "")).finish(8833 op,
8839 self.builder.buildAtomicRmw(8834 ptr,
8840 op,8835 try self.wip.cast(.ptrtoint, operand, try o.lowerType(Type.usize), ""),
8841 ptr.toLlvm(&self.wip),8836 self.sync_scope,
8842 casted_operand.toLlvm(&self.wip),8837 ordering,
8843 @enumFromInt(@intFromEnum(ordering)),8838 ptr_alignment,
8844 single_threaded,8839 "",
8845 ),8840 ), llvm_operand_ty, "");
8846 &self.wip,
8847 );
8848 return self.wip.cast(.inttoptr, uncasted_result, llvm_operand_ty, "");
8849 }8841 }
88508842
8851 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8843 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
...@@ -10581,17 +10573,17 @@ fn toLlvmAtomicRmwBinOp(...@@ -10581,17 +10573,17 @@ fn toLlvmAtomicRmwBinOp(
10581 op: std.builtin.AtomicRmwOp,10573 op: std.builtin.AtomicRmwOp,
10582 is_signed: bool,10574 is_signed: bool,
10583 is_float: bool,10575 is_float: bool,
10584) llvm.AtomicRMWBinOp {10576) Builder.Function.Instruction.AtomicRmw.Operation {
10585 return switch (op) {10577 return switch (op) {
10586 .Xchg => .Xchg,10578 .Xchg => .xchg,
10587 .Add => if (is_float) .FAdd else return .Add,10579 .Add => if (is_float) .fadd else return .add,
10588 .Sub => if (is_float) .FSub else return .Sub,10580 .Sub => if (is_float) .fsub else return .sub,
10589 .And => .And,10581 .And => .@"and",
10590 .Nand => .Nand,10582 .Nand => .nand,
10591 .Or => .Or,10583 .Or => .@"or",
10592 .Xor => .Xor,10584 .Xor => .xor,
10593 .Max => if (is_float) .FMax else if (is_signed) .Max else return .UMax,10585 .Max => if (is_float) .fmax else if (is_signed) .max else return .umax,
10594 .Min => if (is_float) .FMin else if (is_signed) .Min else return .UMin,10586 .Min => if (is_float) .fmin else if (is_signed) .min else return .umin,
10595 };10587 };
10596}10588}
1059710589
src/codegen/llvm/Builder.zig+291-133
...@@ -2177,7 +2177,7 @@ pub const Global = struct {...@@ -2177,7 +2177,7 @@ pub const Global = struct {
2177 if (!builder.useLibLlvm()) return;2177 if (!builder.useLibLlvm()) return;
2178 const index = @intFromEnum(self.unwrap(builder));2178 const index = @intFromEnum(self.unwrap(builder));
2179 const name_slice = self.name(builder).slice(builder) orelse "";2179 const name_slice = self.name(builder).slice(builder) orelse "";
2180 builder.llvm.globals.items[index].setValueName2(name_slice.ptr, name_slice.len);2180 builder.llvm.globals.items[index].setValueName(name_slice.ptr, name_slice.len);
2181 }2181 }
21822182
2183 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {2183 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {
...@@ -3759,12 +3759,15 @@ pub const Function = struct {...@@ -3759,12 +3759,15 @@ pub const Function = struct {
3759 arg,3759 arg,
3760 ashr,3760 ashr,
3761 @"ashr exact",3761 @"ashr exact",
3762 atomicrmw,
3762 bitcast,3763 bitcast,
3763 block,3764 block,
3764 br,3765 br,
3765 br_cond,3766 br_cond,
3766 call,3767 call,
3767 @"call fast",3768 @"call fast",
3769 cmpxchg,
3770 @"cmpxchg weak",
3768 extractelement,3771 extractelement,
3769 extractvalue,3772 extractvalue,
3770 fadd,3773 fadd,
...@@ -3833,8 +3836,6 @@ pub const Function = struct {...@@ -3833,8 +3836,6 @@ pub const Function = struct {
3833 inttoptr,3836 inttoptr,
3834 load,3837 load,
3835 @"load atomic",3838 @"load atomic",
3836 @"load atomic volatile",
3837 @"load volatile",
3838 lshr,3839 lshr,
3839 @"lshr exact",3840 @"lshr exact",
3840 mul,3841 mul,
...@@ -3865,8 +3866,6 @@ pub const Function = struct {...@@ -3865,8 +3866,6 @@ pub const Function = struct {
3865 srem,3866 srem,
3866 store,3867 store,
3867 @"store atomic",3868 @"store atomic",
3868 @"store atomic volatile",
3869 @"store volatile",
3870 sub,3869 sub,
3871 @"sub nsw",3870 @"sub nsw",
3872 @"sub nuw",3871 @"sub nuw",
...@@ -3879,7 +3878,6 @@ pub const Function = struct {...@@ -3879,7 +3878,6 @@ pub const Function = struct {
3879 @"udiv exact",3878 @"udiv exact",
3880 urem,3879 urem,
3881 uitofp,3880 uitofp,
3882 unimplemented,
3883 @"unreachable",3881 @"unreachable",
3884 va_arg,3882 va_arg,
3885 xor,3883 xor,
...@@ -3920,8 +3918,6 @@ pub const Function = struct {...@@ -3920,8 +3918,6 @@ pub const Function = struct {
3920 .@"ret void",3918 .@"ret void",
3921 .store,3919 .store,
3922 .@"store atomic",3920 .@"store atomic",
3923 .@"store atomic volatile",
3924 .@"store volatile",
3925 .@"switch",3921 .@"switch",
3926 .@"unreachable",3922 .@"unreachable",
3927 => false,3923 => false,
...@@ -3933,7 +3929,6 @@ pub const Function = struct {...@@ -3933,7 +3929,6 @@ pub const Function = struct {
3933 .@"notail call fast",3929 .@"notail call fast",
3934 .@"tail call",3930 .@"tail call",
3935 .@"tail call fast",3931 .@"tail call fast",
3936 .unimplemented,
3937 => self.typeOfWip(wip) != .void,3932 => self.typeOfWip(wip) != .void,
3938 else => true,3933 else => true,
3939 };3934 };
...@@ -4003,6 +3998,7 @@ pub const Function = struct {...@@ -4003,6 +3998,7 @@ pub const Function = struct {
4003 ),3998 ),
4004 .arg => wip.function.typeOf(wip.builder)3999 .arg => wip.function.typeOf(wip.builder)
4005 .functionParameters(wip.builder)[instruction.data],4000 .functionParameters(wip.builder)[instruction.data],
4001 .atomicrmw => wip.extraData(AtomicRmw, instruction.data).val.typeOfWip(wip),
4006 .block => .label,4002 .block => .label,
4007 .br,4003 .br,
4008 .br_cond,4004 .br_cond,
...@@ -4011,8 +4007,6 @@ pub const Function = struct {...@@ -4011,8 +4007,6 @@ pub const Function = struct {
4011 .@"ret void",4007 .@"ret void",
4012 .store,4008 .store,
4013 .@"store atomic",4009 .@"store atomic",
4014 .@"store atomic volatile",
4015 .@"store volatile",
4016 .@"switch",4010 .@"switch",
4017 .@"unreachable",4011 .@"unreachable",
4018 => .none,4012 => .none,
...@@ -4025,6 +4019,12 @@ pub const Function = struct {...@@ -4025,6 +4019,12 @@ pub const Function = struct {
4025 .@"tail call",4019 .@"tail call",
4026 .@"tail call fast",4020 .@"tail call fast",
4027 => wip.extraData(Call, instruction.data).ty.functionReturn(wip.builder),4021 => wip.extraData(Call, instruction.data).ty.functionReturn(wip.builder),
4022 .cmpxchg,
4023 .@"cmpxchg weak",
4024 => wip.builder.structTypeAssumeCapacity(.normal, &.{
4025 wip.extraData(CmpXchg, instruction.data).cmp.typeOfWip(wip),
4026 .i1,
4027 }) catch unreachable,
4028 .extractelement => wip.extraData(ExtractElement, instruction.data)4028 .extractelement => wip.extraData(ExtractElement, instruction.data)
4029 .val.typeOfWip(wip).childType(wip.builder),4029 .val.typeOfWip(wip).childType(wip.builder),
4030 .extractvalue => {4030 .extractvalue => {
...@@ -4096,8 +4096,6 @@ pub const Function = struct {...@@ -4096,8 +4096,6 @@ pub const Function = struct {
4096 .insertvalue => wip.extraData(InsertValue, instruction.data).val.typeOfWip(wip),4096 .insertvalue => wip.extraData(InsertValue, instruction.data).val.typeOfWip(wip),
4097 .load,4097 .load,
4098 .@"load atomic",4098 .@"load atomic",
4099 .@"load atomic volatile",
4100 .@"load volatile",
4101 => wip.extraData(Load, instruction.data).type,4099 => wip.extraData(Load, instruction.data).type,
4102 .phi,4100 .phi,
4103 .@"phi fast",4101 .@"phi fast",
...@@ -4112,7 +4110,6 @@ pub const Function = struct {...@@ -4112,7 +4110,6 @@ pub const Function = struct {
4112 wip.builder,4110 wip.builder,
4113 );4111 );
4114 },4112 },
4115 .unimplemented => @enumFromInt(instruction.data),
4116 .va_arg => wip.extraData(VaArg, instruction.data).type,4113 .va_arg => wip.extraData(VaArg, instruction.data).type,
4117 };4114 };
4118 }4115 }
...@@ -4186,6 +4183,8 @@ pub const Function = struct {...@@ -4186,6 +4183,8 @@ pub const Function = struct {
4186 ),4183 ),
4187 .arg => function.global.typeOf(builder)4184 .arg => function.global.typeOf(builder)
4188 .functionParameters(builder)[instruction.data],4185 .functionParameters(builder)[instruction.data],
4186 .atomicrmw => function.extraData(AtomicRmw, instruction.data)
4187 .val.typeOf(function_index, builder),
4189 .block => .label,4188 .block => .label,
4190 .br,4189 .br,
4191 .br_cond,4190 .br_cond,
...@@ -4194,8 +4193,6 @@ pub const Function = struct {...@@ -4194,8 +4193,6 @@ pub const Function = struct {
4194 .@"ret void",4193 .@"ret void",
4195 .store,4194 .store,
4196 .@"store atomic",4195 .@"store atomic",
4197 .@"store atomic volatile",
4198 .@"store volatile",
4199 .@"switch",4196 .@"switch",
4200 .@"unreachable",4197 .@"unreachable",
4201 => .none,4198 => .none,
...@@ -4208,6 +4205,13 @@ pub const Function = struct {...@@ -4208,6 +4205,13 @@ pub const Function = struct {
4208 .@"tail call",4205 .@"tail call",
4209 .@"tail call fast",4206 .@"tail call fast",
4210 => function.extraData(Call, instruction.data).ty.functionReturn(builder),4207 => function.extraData(Call, instruction.data).ty.functionReturn(builder),
4208 .cmpxchg,
4209 .@"cmpxchg weak",
4210 => builder.structTypeAssumeCapacity(.normal, &.{
4211 function.extraData(CmpXchg, instruction.data)
4212 .cmp.typeOf(function_index, builder),
4213 .i1,
4214 }) catch unreachable,
4211 .extractelement => function.extraData(ExtractElement, instruction.data)4215 .extractelement => function.extraData(ExtractElement, instruction.data)
4212 .val.typeOf(function_index, builder).childType(builder),4216 .val.typeOf(function_index, builder).childType(builder),
4213 .extractvalue => {4217 .extractvalue => {
...@@ -4282,8 +4286,6 @@ pub const Function = struct {...@@ -4282,8 +4286,6 @@ pub const Function = struct {
4282 .val.typeOf(function_index, builder),4286 .val.typeOf(function_index, builder),
4283 .load,4287 .load,
4284 .@"load atomic",4288 .@"load atomic",
4285 .@"load atomic volatile",
4286 .@"load volatile",
4287 => function.extraData(Load, instruction.data).type,4289 => function.extraData(Load, instruction.data).type,
4288 .phi,4290 .phi,
4289 .@"phi fast",4291 .@"phi fast",
...@@ -4298,7 +4300,6 @@ pub const Function = struct {...@@ -4298,7 +4300,6 @@ pub const Function = struct {
4298 builder,4300 builder,
4299 );4301 );
4300 },4302 },
4301 .unimplemented => @enumFromInt(instruction.data),
4302 .va_arg => function.extraData(VaArg, instruction.data).type,4303 .va_arg => function.extraData(VaArg, instruction.data).type,
4303 };4304 };
4304 }4305 }
...@@ -4346,7 +4347,7 @@ pub const Function = struct {...@@ -4346,7 +4347,7 @@ pub const Function = struct {
4346 return wip.llvm.instructions.items[@intFromEnum(self)];4347 return wip.llvm.instructions.items[@intFromEnum(self)];
4347 }4348 }
43484349
4349 fn llvmName(self: Instruction.Index, wip: *const WipFunction) [*:0]const u8 {4350 fn llvmName(self: Instruction.Index, wip: *const WipFunction) [:0]const u8 {
4350 return if (wip.builder.strip)4351 return if (wip.builder.strip)
4351 ""4352 ""
4352 else4353 else
...@@ -4419,15 +4420,49 @@ pub const Function = struct {...@@ -4419,15 +4420,49 @@ pub const Function = struct {
4419 };4420 };
44204421
4421 pub const Load = struct {4422 pub const Load = struct {
4423 info: MemoryAccessInfo,
4422 type: Type,4424 type: Type,
4423 ptr: Value,4425 ptr: Value,
4424 info: MemoryAccessInfo,
4425 };4426 };
44264427
4427 pub const Store = struct {4428 pub const Store = struct {
4429 info: MemoryAccessInfo,
4428 val: Value,4430 val: Value,
4429 ptr: Value,4431 ptr: Value,
4432 };
4433
4434 pub const CmpXchg = struct {
4430 info: MemoryAccessInfo,4435 info: MemoryAccessInfo,
4436 ptr: Value,
4437 cmp: Value,
4438 new: Value,
4439
4440 pub const Kind = enum { strong, weak };
4441 };
4442
4443 pub const AtomicRmw = struct {
4444 info: MemoryAccessInfo,
4445 ptr: Value,
4446 val: Value,
4447
4448 pub const Operation = enum(u5) {
4449 xchg,
4450 add,
4451 sub,
4452 @"and",
4453 nand,
4454 @"or",
4455 xor,
4456 max,
4457 min,
4458 umax,
4459 umin,
4460 fadd,
4461 fsub,
4462 fmax,
4463 fmin,
4464 none = std.math.maxInt(u5),
4465 };
4431 };4466 };
44324467
4433 pub const GetElementPtr = struct {4468 pub const GetElementPtr = struct {
...@@ -5163,21 +5198,21 @@ pub const WipFunction = struct {...@@ -5163,21 +5198,21 @@ pub const WipFunction = struct {
51635198
5164 pub fn load(5199 pub fn load(
5165 self: *WipFunction,5200 self: *WipFunction,
5166 kind: MemoryAccessKind,5201 access_kind: MemoryAccessKind,
5167 ty: Type,5202 ty: Type,
5168 ptr: Value,5203 ptr: Value,
5169 alignment: Alignment,5204 alignment: Alignment,
5170 name: []const u8,5205 name: []const u8,
5171 ) Allocator.Error!Value {5206 ) Allocator.Error!Value {
5172 return self.loadAtomic(kind, ty, ptr, .system, .none, alignment, name);5207 return self.loadAtomic(access_kind, ty, ptr, .system, .none, alignment, name);
5173 }5208 }
51745209
5175 pub fn loadAtomic(5210 pub fn loadAtomic(
5176 self: *WipFunction,5211 self: *WipFunction,
5177 kind: MemoryAccessKind,5212 access_kind: MemoryAccessKind,
5178 ty: Type,5213 ty: Type,
5179 ptr: Value,5214 ptr: Value,
5180 scope: SyncScope,5215 sync_scope: SyncScope,
5181 ordering: AtomicOrdering,5216 ordering: AtomicOrdering,
5182 alignment: Alignment,5217 alignment: Alignment,
5183 name: []const u8,5218 name: []const u8,
...@@ -5186,22 +5221,21 @@ pub const WipFunction = struct {...@@ -5186,22 +5221,21 @@ pub const WipFunction = struct {
5186 try self.ensureUnusedExtraCapacity(1, Instruction.Load, 0);5221 try self.ensureUnusedExtraCapacity(1, Instruction.Load, 0);
5187 const instruction = try self.addInst(name, .{5222 const instruction = try self.addInst(name, .{
5188 .tag = switch (ordering) {5223 .tag = switch (ordering) {
5189 .none => switch (kind) {5224 .none => .load,
5190 .normal => .load,5225 else => .@"load atomic",
5191 .@"volatile" => .@"load volatile",
5192 },
5193 else => switch (kind) {
5194 .normal => .@"load atomic",
5195 .@"volatile" => .@"load atomic volatile",
5196 },
5197 },5226 },
5198 .data = self.addExtraAssumeCapacity(Instruction.Load{5227 .data = self.addExtraAssumeCapacity(Instruction.Load{
5228 .info = .{
5229 .access_kind = access_kind,
5230 .sync_scope = switch (ordering) {
5231 .none => .system,
5232 else => sync_scope,
5233 },
5234 .success_ordering = ordering,
5235 .alignment = alignment,
5236 },
5199 .type = ty,5237 .type = ty,
5200 .ptr = ptr,5238 .ptr = ptr,
5201 .info = .{ .scope = switch (ordering) {
5202 .none => .system,
5203 else => scope,
5204 }, .ordering = ordering, .alignment = alignment },
5205 }),5239 }),
5206 });5240 });
5207 if (self.builder.useLibLlvm()) {5241 if (self.builder.useLibLlvm()) {
...@@ -5210,6 +5244,7 @@ pub const WipFunction = struct {...@@ -5210,6 +5244,7 @@ pub const WipFunction = struct {
5210 ptr.toLlvm(self),5244 ptr.toLlvm(self),
5211 instruction.llvmName(self),5245 instruction.llvmName(self),
5212 );5246 );
5247 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5213 if (ordering != .none) llvm_instruction.setOrdering(@enumFromInt(@intFromEnum(ordering)));5248 if (ordering != .none) llvm_instruction.setOrdering(@enumFromInt(@intFromEnum(ordering)));
5214 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));5249 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5215 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);5250 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
...@@ -5229,10 +5264,10 @@ pub const WipFunction = struct {...@@ -5229,10 +5264,10 @@ pub const WipFunction = struct {
52295264
5230 pub fn storeAtomic(5265 pub fn storeAtomic(
5231 self: *WipFunction,5266 self: *WipFunction,
5232 kind: MemoryAccessKind,5267 access_kind: MemoryAccessKind,
5233 val: Value,5268 val: Value,
5234 ptr: Value,5269 ptr: Value,
5235 scope: SyncScope,5270 sync_scope: SyncScope,
5236 ordering: AtomicOrdering,5271 ordering: AtomicOrdering,
5237 alignment: Alignment,5272 alignment: Alignment,
5238 ) Allocator.Error!Instruction.Index {5273 ) Allocator.Error!Instruction.Index {
...@@ -5240,30 +5275,26 @@ pub const WipFunction = struct {...@@ -5240,30 +5275,26 @@ pub const WipFunction = struct {
5240 try self.ensureUnusedExtraCapacity(1, Instruction.Store, 0);5275 try self.ensureUnusedExtraCapacity(1, Instruction.Store, 0);
5241 const instruction = try self.addInst(null, .{5276 const instruction = try self.addInst(null, .{
5242 .tag = switch (ordering) {5277 .tag = switch (ordering) {
5243 .none => switch (kind) {5278 .none => .store,
5244 .normal => .store,5279 else => .@"store atomic",
5245 .@"volatile" => .@"store volatile",
5246 },
5247 else => switch (kind) {
5248 .normal => .@"store atomic",
5249 .@"volatile" => .@"store atomic volatile",
5250 },
5251 },5280 },
5252 .data = self.addExtraAssumeCapacity(Instruction.Store{5281 .data = self.addExtraAssumeCapacity(Instruction.Store{
5282 .info = .{
5283 .access_kind = access_kind,
5284 .sync_scope = switch (ordering) {
5285 .none => .system,
5286 else => sync_scope,
5287 },
5288 .success_ordering = ordering,
5289 .alignment = alignment,
5290 },
5253 .val = val,5291 .val = val,
5254 .ptr = ptr,5292 .ptr = ptr,
5255 .info = .{ .scope = switch (ordering) {
5256 .none => .system,
5257 else => scope,
5258 }, .ordering = ordering, .alignment = alignment },
5259 }),5293 }),
5260 });5294 });
5261 if (self.builder.useLibLlvm()) {5295 if (self.builder.useLibLlvm()) {
5262 const llvm_instruction = self.llvm.builder.buildStore(val.toLlvm(self), ptr.toLlvm(self));5296 const llvm_instruction = self.llvm.builder.buildStore(val.toLlvm(self), ptr.toLlvm(self));
5263 switch (kind) {5297 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5264 .normal => {},
5265 .@"volatile" => llvm_instruction.setVolatile(.True),
5266 }
5267 if (ordering != .none) llvm_instruction.setOrdering(@enumFromInt(@intFromEnum(ordering)));5298 if (ordering != .none) llvm_instruction.setOrdering(@enumFromInt(@intFromEnum(ordering)));
5268 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));5299 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5269 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);5300 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
...@@ -5273,7 +5304,7 @@ pub const WipFunction = struct {...@@ -5273,7 +5304,7 @@ pub const WipFunction = struct {
52735304
5274 pub fn fence(5305 pub fn fence(
5275 self: *WipFunction,5306 self: *WipFunction,
5276 scope: SyncScope,5307 sync_scope: SyncScope,
5277 ordering: AtomicOrdering,5308 ordering: AtomicOrdering,
5278 ) Allocator.Error!Instruction.Index {5309 ) Allocator.Error!Instruction.Index {
5279 assert(ordering != .none);5310 assert(ordering != .none);
...@@ -5281,21 +5312,130 @@ pub const WipFunction = struct {...@@ -5281,21 +5312,130 @@ pub const WipFunction = struct {
5281 const instruction = try self.addInst(null, .{5312 const instruction = try self.addInst(null, .{
5282 .tag = .fence,5313 .tag = .fence,
5283 .data = @bitCast(MemoryAccessInfo{5314 .data = @bitCast(MemoryAccessInfo{
5284 .scope = scope,5315 .sync_scope = sync_scope,
5285 .ordering = ordering,5316 .success_ordering = ordering,
5286 .alignment = undefined,
5287 }),5317 }),
5288 });5318 });
5289 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(5319 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
5290 self.llvm.builder.buildFence(5320 self.llvm.builder.buildFence(
5291 @enumFromInt(@intFromEnum(ordering)),5321 @enumFromInt(@intFromEnum(ordering)),
5292 llvm.Bool.fromBool(scope == .singlethread),5322 llvm.Bool.fromBool(sync_scope == .singlethread),
5293 "",5323 "",
5294 ),5324 ),
5295 );5325 );
5296 return instruction;5326 return instruction;
5297 }5327 }
52985328
5329 pub fn cmpxchg(
5330 self: *WipFunction,
5331 kind: Instruction.CmpXchg.Kind,
5332 access_kind: MemoryAccessKind,
5333 ptr: Value,
5334 cmp: Value,
5335 new: Value,
5336 sync_scope: SyncScope,
5337 success_ordering: AtomicOrdering,
5338 failure_ordering: AtomicOrdering,
5339 alignment: Alignment,
5340 name: []const u8,
5341 ) Allocator.Error!Value {
5342 assert(ptr.typeOfWip(self).isPointer(self.builder));
5343 const ty = cmp.typeOfWip(self);
5344 assert(ty == new.typeOfWip(self));
5345 assert(success_ordering != .none);
5346 assert(failure_ordering != .none);
5347
5348 _ = try self.builder.structType(.normal, &.{ ty, .i1 });
5349 try self.ensureUnusedExtraCapacity(1, Instruction.CmpXchg, 0);
5350 const instruction = try self.addInst(name, .{
5351 .tag = switch (kind) {
5352 .strong => .cmpxchg,
5353 .weak => .@"cmpxchg weak",
5354 },
5355 .data = self.addExtraAssumeCapacity(Instruction.CmpXchg{
5356 .info = .{
5357 .access_kind = access_kind,
5358 .sync_scope = sync_scope,
5359 .success_ordering = success_ordering,
5360 .failure_ordering = failure_ordering,
5361 .alignment = alignment,
5362 },
5363 .ptr = ptr,
5364 .cmp = cmp,
5365 .new = new,
5366 }),
5367 });
5368 if (self.builder.useLibLlvm()) {
5369 const llvm_instruction = self.llvm.builder.buildAtomicCmpXchg(
5370 ptr.toLlvm(self),
5371 cmp.toLlvm(self),
5372 new.toLlvm(self),
5373 @enumFromInt(@intFromEnum(success_ordering)),
5374 @enumFromInt(@intFromEnum(failure_ordering)),
5375 llvm.Bool.fromBool(sync_scope == .singlethread),
5376 );
5377 if (kind == .weak) llvm_instruction.setWeak(.True);
5378 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5379 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5380 const llvm_name = instruction.llvmName(self);
5381 if (llvm_name.len > 0) llvm_instruction.setValueName(
5382 llvm_name.ptr,
5383 @intCast(llvm_name.len),
5384 );
5385 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5386 }
5387 return instruction.toValue();
5388 }
5389
5390 pub fn atomicrmw(
5391 self: *WipFunction,
5392 access_kind: MemoryAccessKind,
5393 operation: Instruction.AtomicRmw.Operation,
5394 ptr: Value,
5395 val: Value,
5396 sync_scope: SyncScope,
5397 ordering: AtomicOrdering,
5398 alignment: Alignment,
5399 name: []const u8,
5400 ) Allocator.Error!Value {
5401 assert(ptr.typeOfWip(self).isPointer(self.builder));
5402 assert(ordering != .none);
5403
5404 try self.ensureUnusedExtraCapacity(1, Instruction.AtomicRmw, 0);
5405 const instruction = try self.addInst(name, .{
5406 .tag = .atomicrmw,
5407 .data = self.addExtraAssumeCapacity(Instruction.AtomicRmw{
5408 .info = .{
5409 .access_kind = access_kind,
5410 .atomic_rmw_operation = operation,
5411 .sync_scope = sync_scope,
5412 .success_ordering = ordering,
5413 .alignment = alignment,
5414 },
5415 .ptr = ptr,
5416 .val = val,
5417 }),
5418 });
5419 if (self.builder.useLibLlvm()) {
5420 const llvm_instruction = self.llvm.builder.buildAtomicRmw(
5421 @enumFromInt(@intFromEnum(operation)),
5422 ptr.toLlvm(self),
5423 val.toLlvm(self),
5424 @enumFromInt(@intFromEnum(ordering)),
5425 llvm.Bool.fromBool(sync_scope == .singlethread),
5426 );
5427 if (access_kind == .@"volatile") llvm_instruction.setVolatile(.True);
5428 if (alignment.toByteUnits()) |bytes| llvm_instruction.setAlignment(@intCast(bytes));
5429 const llvm_name = instruction.llvmName(self);
5430 if (llvm_name.len > 0) llvm_instruction.setValueName(
5431 llvm_name.ptr,
5432 @intCast(llvm_name.len),
5433 );
5434 self.llvm.instructions.appendAssumeCapacity(llvm_instruction);
5435 }
5436 return instruction.toValue();
5437 }
5438
5299 pub fn gep(5439 pub fn gep(
5300 self: *WipFunction,5440 self: *WipFunction,
5301 kind: Instruction.GetElementPtr.Kind,5441 kind: Instruction.GetElementPtr.Kind,
...@@ -5747,30 +5887,6 @@ pub const WipFunction = struct {...@@ -5747,30 +5887,6 @@ pub const WipFunction = struct {
5747 return instruction.toValue();5887 return instruction.toValue();
5748 }5888 }
57495889
5750 pub const WipUnimplemented = struct {
5751 instruction: Instruction.Index,
5752
5753 pub fn finish(self: WipUnimplemented, val: *llvm.Value, wip: *WipFunction) Value {
5754 assert(wip.builder.useLibLlvm());
5755 wip.llvm.instructions.items[@intFromEnum(self.instruction)] = val;
5756 return self.instruction.toValue();
5757 }
5758 };
5759
5760 pub fn unimplemented(
5761 self: *WipFunction,
5762 ty: Type,
5763 name: []const u8,
5764 ) Allocator.Error!WipUnimplemented {
5765 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
5766 const instruction = try self.addInst(name, .{
5767 .tag = .unimplemented,
5768 .data = @intFromEnum(ty),
5769 });
5770 if (self.builder.useLibLlvm()) _ = self.llvm.instructions.addOneAssumeCapacity();
5771 return .{ .instruction = instruction };
5772 }
5773
5774 pub fn finish(self: *WipFunction) Allocator.Error!void {5890 pub fn finish(self: *WipFunction) Allocator.Error!void {
5775 const gpa = self.builder.gpa;5891 const gpa = self.builder.gpa;
5776 const function = self.function.ptr(self.builder);5892 const function = self.function.ptr(self.builder);
...@@ -6035,19 +6151,19 @@ pub const WipFunction = struct {...@@ -6035,19 +6151,19 @@ pub const WipFunction = struct {
6035 .arg,6151 .arg,
6036 .block,6152 .block,
6037 => unreachable,6153 => unreachable,
6154 .atomicrmw => {
6155 const extra = self.extraData(Instruction.AtomicRmw, instruction.data);
6156 instruction.data = wip_extra.addExtra(Instruction.AtomicRmw{
6157 .info = extra.info,
6158 .ptr = instructions.map(extra.ptr),
6159 .val = instructions.map(extra.val),
6160 });
6161 },
6038 .br,6162 .br,
6039 .fence,6163 .fence,
6040 .@"ret void",6164 .@"ret void",
6041 .unimplemented,
6042 .@"unreachable",6165 .@"unreachable",
6043 => {},6166 => {},
6044 .extractelement => {
6045 const extra = self.extraData(Instruction.ExtractElement, instruction.data);
6046 instruction.data = wip_extra.addExtra(Instruction.ExtractElement{
6047 .val = instructions.map(extra.val),
6048 .index = instructions.map(extra.index),
6049 });
6050 },
6051 .br_cond => {6167 .br_cond => {
6052 const extra = self.extraData(Instruction.BrCond, instruction.data);6168 const extra = self.extraData(Instruction.BrCond, instruction.data);
6053 instruction.data = wip_extra.addExtra(Instruction.BrCond{6169 instruction.data = wip_extra.addExtra(Instruction.BrCond{
...@@ -6076,6 +6192,24 @@ pub const WipFunction = struct {...@@ -6076,6 +6192,24 @@ pub const WipFunction = struct {
6076 });6192 });
6077 wip_extra.appendMappedValues(args, instructions);6193 wip_extra.appendMappedValues(args, instructions);
6078 },6194 },
6195 .cmpxchg,
6196 .@"cmpxchg weak",
6197 => {
6198 const extra = self.extraData(Instruction.CmpXchg, instruction.data);
6199 instruction.data = wip_extra.addExtra(Instruction.CmpXchg{
6200 .info = extra.info,
6201 .ptr = instructions.map(extra.ptr),
6202 .cmp = instructions.map(extra.cmp),
6203 .new = instructions.map(extra.new),
6204 });
6205 },
6206 .extractelement => {
6207 const extra = self.extraData(Instruction.ExtractElement, instruction.data);
6208 instruction.data = wip_extra.addExtra(Instruction.ExtractElement{
6209 .val = instructions.map(extra.val),
6210 .index = instructions.map(extra.index),
6211 });
6212 },
6079 .extractvalue => {6213 .extractvalue => {
6080 var extra = self.extraDataTrail(Instruction.ExtractValue, instruction.data);6214 var extra = self.extraDataTrail(Instruction.ExtractValue, instruction.data);
6081 const indices = extra.trail.next(extra.data.indices_len, u32, self);6215 const indices = extra.trail.next(extra.data.indices_len, u32, self);
...@@ -6121,8 +6255,6 @@ pub const WipFunction = struct {...@@ -6121,8 +6255,6 @@ pub const WipFunction = struct {
6121 },6255 },
6122 .load,6256 .load,
6123 .@"load atomic",6257 .@"load atomic",
6124 .@"load atomic volatile",
6125 .@"load volatile",
6126 => {6258 => {
6127 const extra = self.extraData(Instruction.Load, instruction.data);6259 const extra = self.extraData(Instruction.Load, instruction.data);
6128 instruction.data = wip_extra.addExtra(Instruction.Load{6260 instruction.data = wip_extra.addExtra(Instruction.Load{
...@@ -6164,8 +6296,6 @@ pub const WipFunction = struct {...@@ -6164,8 +6296,6 @@ pub const WipFunction = struct {
6164 },6296 },
6165 .store,6297 .store,
6166 .@"store atomic",6298 .@"store atomic",
6167 .@"store atomic volatile",
6168 .@"store volatile",
6169 => {6299 => {
6170 const extra = self.extraData(Instruction.Store, instruction.data);6300 const extra = self.extraData(Instruction.Store, instruction.data);
6171 instruction.data = wip_extra.addExtra(Instruction.Store{6301 instruction.data = wip_extra.addExtra(Instruction.Store{
...@@ -6619,6 +6749,15 @@ pub const IntegerCondition = enum(u6) {...@@ -6619,6 +6749,15 @@ pub const IntegerCondition = enum(u6) {
6619pub const MemoryAccessKind = enum(u1) {6749pub const MemoryAccessKind = enum(u1) {
6620 normal,6750 normal,
6621 @"volatile",6751 @"volatile",
6752
6753 pub fn format(
6754 self: MemoryAccessKind,
6755 comptime prefix: []const u8,
6756 _: std.fmt.FormatOptions,
6757 writer: anytype,
6758 ) @TypeOf(writer).Error!void {
6759 if (self != .normal) try writer.print("{s}{s}", .{ prefix, @tagName(self) });
6760 }
6622};6761};
66236762
6624pub const SyncScope = enum(u1) {6763pub const SyncScope = enum(u1) {
...@@ -6632,7 +6771,7 @@ pub const SyncScope = enum(u1) {...@@ -6632,7 +6771,7 @@ pub const SyncScope = enum(u1) {
6632 writer: anytype,6771 writer: anytype,
6633 ) @TypeOf(writer).Error!void {6772 ) @TypeOf(writer).Error!void {
6634 if (self != .system) try writer.print(6773 if (self != .system) try writer.print(
6635 \\{s} syncscope("{s}")6774 \\{s}syncscope("{s}")
6636 , .{ prefix, @tagName(self) });6775 , .{ prefix, @tagName(self) });
6637 }6776 }
6638};6777};
...@@ -6652,15 +6791,18 @@ pub const AtomicOrdering = enum(u3) {...@@ -6652,15 +6791,18 @@ pub const AtomicOrdering = enum(u3) {
6652 _: std.fmt.FormatOptions,6791 _: std.fmt.FormatOptions,
6653 writer: anytype,6792 writer: anytype,
6654 ) @TypeOf(writer).Error!void {6793 ) @TypeOf(writer).Error!void {
6655 if (self != .none) try writer.print("{s} {s}", .{ prefix, @tagName(self) });6794 if (self != .none) try writer.print("{s}{s}", .{ prefix, @tagName(self) });
6656 }6795 }
6657};6796};
66586797
6659const MemoryAccessInfo = packed struct(u32) {6798const MemoryAccessInfo = packed struct(u32) {
6660 scope: SyncScope,6799 access_kind: MemoryAccessKind = .normal,
6661 ordering: AtomicOrdering,6800 atomic_rmw_operation: Function.Instruction.AtomicRmw.Operation = .none,
6662 alignment: Alignment,6801 sync_scope: SyncScope,
6663 _: u22 = undefined,6802 success_ordering: AtomicOrdering,
6803 failure_ordering: AtomicOrdering = .none,
6804 alignment: Alignment = .default,
6805 _: u13 = undefined,
6664};6806};
66656807
6666pub const FastMath = packed struct(u32) {6808pub const FastMath = packed struct(u32) {
...@@ -7542,7 +7684,7 @@ pub fn init(options: Options) InitError!Builder {...@@ -7542,7 +7684,7 @@ pub fn init(options: Options) InitError!Builder {
7542 if (options.name.len > 0) self.source_filename = try self.string(options.name);7684 if (options.name.len > 0) self.source_filename = try self.string(options.name);
7543 self.initializeLLVMTarget(options.target.cpu.arch);7685 self.initializeLLVMTarget(options.target.cpu.arch);
7544 if (self.useLibLlvm()) self.llvm.module = llvm.Module.createWithName(7686 if (self.useLibLlvm()) self.llvm.module = llvm.Module.createWithName(
7545 (self.source_filename.slice(&self) orelse "").ptr,7687 (self.source_filename.slice(&self) orelse ""),
7546 self.llvm.context,7688 self.llvm.context,
7547 );7689 );
75487690
...@@ -8983,6 +9125,21 @@ pub fn printUnbuffered(...@@ -8983,6 +9125,21 @@ pub fn printUnbuffered(
8983 });9125 });
8984 },9126 },
8985 .arg => unreachable,9127 .arg => unreachable,
9128 .atomicrmw => |tag| {
9129 const extra =
9130 function.extraData(Function.Instruction.AtomicRmw, instruction.data);
9131 try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }\n", .{
9132 instruction_index.name(&function).fmt(self),
9133 @tagName(tag),
9134 extra.info.access_kind,
9135 @tagName(extra.info.atomic_rmw_operation),
9136 extra.ptr.fmt(function_index, self),
9137 extra.val.fmt(function_index, self),
9138 extra.info.sync_scope,
9139 extra.info.success_ordering,
9140 extra.info.alignment,
9141 });
9142 },
8986 .block => {9143 .block => {
8987 block_incoming_len = instruction.data;9144 block_incoming_len = instruction.data;
8988 const name = instruction_index.name(&function);9145 const name = instruction_index.name(&function);
...@@ -9056,6 +9213,24 @@ pub fn printUnbuffered(...@@ -9056,6 +9213,24 @@ pub fn printUnbuffered(
9056 });9213 });
9057 try writer.writeByte('\n');9214 try writer.writeByte('\n');
9058 },9215 },
9216 .cmpxchg,
9217 .@"cmpxchg weak",
9218 => |tag| {
9219 const extra =
9220 function.extraData(Function.Instruction.CmpXchg, instruction.data);
9221 try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }\n", .{
9222 instruction_index.name(&function).fmt(self),
9223 @tagName(tag),
9224 extra.info.access_kind,
9225 extra.ptr.fmt(function_index, self),
9226 extra.cmp.fmt(function_index, self),
9227 extra.new.fmt(function_index, self),
9228 extra.info.sync_scope,
9229 extra.info.success_ordering,
9230 extra.info.failure_ordering,
9231 extra.info.alignment,
9232 });
9233 },
9059 .extractelement => |tag| {9234 .extractelement => |tag| {
9060 const extra = function.extraData(9235 const extra = function.extraData(
9061 Function.Instruction.ExtractElement,9236 Function.Instruction.ExtractElement,
...@@ -9084,7 +9259,11 @@ pub fn printUnbuffered(...@@ -9084,7 +9259,11 @@ pub fn printUnbuffered(
9084 },9259 },
9085 .fence => |tag| {9260 .fence => |tag| {
9086 const info: MemoryAccessInfo = @bitCast(instruction.data);9261 const info: MemoryAccessInfo = @bitCast(instruction.data);
9087 try writer.print(" {s}{}{}", .{ @tagName(tag), info.scope, info.ordering });9262 try writer.print(" {s}{ }{ }", .{
9263 @tagName(tag),
9264 info.sync_scope,
9265 info.success_ordering,
9266 });
9088 },9267 },
9089 .fneg,9268 .fneg,
9090 .@"fneg fast",9269 .@"fneg fast",
...@@ -9145,18 +9324,17 @@ pub fn printUnbuffered(...@@ -9145,18 +9324,17 @@ pub fn printUnbuffered(
9145 },9324 },
9146 .load,9325 .load,
9147 .@"load atomic",9326 .@"load atomic",
9148 .@"load atomic volatile",
9149 .@"load volatile",
9150 => |tag| {9327 => |tag| {
9151 const extra =9328 const extra =
9152 function.extraData(Function.Instruction.Load, instruction.data);9329 function.extraData(Function.Instruction.Load, instruction.data);
9153 try writer.print(" %{} = {s} {%}, {%}{}{}{, }\n", .{9330 try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }\n", .{
9154 instruction_index.name(&function).fmt(self),9331 instruction_index.name(&function).fmt(self),
9155 @tagName(tag),9332 @tagName(tag),
9333 extra.info.access_kind,
9156 extra.type.fmt(self),9334 extra.type.fmt(self),
9157 extra.ptr.fmt(function_index, self),9335 extra.ptr.fmt(function_index, self),
9158 extra.info.scope,9336 extra.info.sync_scope,
9159 extra.info.ordering,9337 extra.info.success_ordering,
9160 extra.info.alignment,9338 extra.info.alignment,
9161 });9339 });
9162 },9340 },
...@@ -9220,17 +9398,16 @@ pub fn printUnbuffered(...@@ -9220,17 +9398,16 @@ pub fn printUnbuffered(
9220 },9398 },
9221 .store,9399 .store,
9222 .@"store atomic",9400 .@"store atomic",
9223 .@"store atomic volatile",
9224 .@"store volatile",
9225 => |tag| {9401 => |tag| {
9226 const extra =9402 const extra =
9227 function.extraData(Function.Instruction.Store, instruction.data);9403 function.extraData(Function.Instruction.Store, instruction.data);
9228 try writer.print(" {s} {%}, {%}{}{}{, }\n", .{9404 try writer.print(" {s}{ } {%}, {%}{ }{ }{, }\n", .{
9229 @tagName(tag),9405 @tagName(tag),
9406 extra.info.access_kind,
9230 extra.val.fmt(function_index, self),9407 extra.val.fmt(function_index, self),
9231 extra.ptr.fmt(function_index, self),9408 extra.ptr.fmt(function_index, self),
9232 extra.info.scope,9409 extra.info.sync_scope,
9233 extra.info.ordering,9410 extra.info.success_ordering,
9234 extra.info.alignment,9411 extra.info.alignment,
9235 });9412 });
9236 },9413 },
...@@ -9254,25 +9431,6 @@ pub fn printUnbuffered(...@@ -9254,25 +9431,6 @@ pub fn printUnbuffered(
9254 );9431 );
9255 try writer.writeAll(" ]\n");9432 try writer.writeAll(" ]\n");
9256 },9433 },
9257 .unimplemented => |tag| {
9258 const ty: Type = @enumFromInt(instruction.data);
9259 if (true) {
9260 try writer.writeAll(" ");
9261 switch (ty) {
9262 .none, .void => {},
9263 else => try writer.print("%{} = ", .{
9264 instruction_index.name(&function).fmt(self),
9265 }),
9266 }
9267 try writer.print("{s} {%}\n", .{ @tagName(tag), ty.fmt(self) });
9268 } else switch (ty) {
9269 .none, .void => {},
9270 else => try writer.print(" %{} = load {%}, ptr undef\n", .{
9271 instruction_index.name(&function).fmt(self),
9272 ty.fmt(self),
9273 }),
9274 }
9275 },
9276 .va_arg => |tag| {9434 .va_arg => |tag| {
9277 const extra =9435 const extra =
9278 function.extraData(Function.Instruction.VaArg, instruction.data);9436 function.extraData(Function.Instruction.VaArg, instruction.data);
src/codegen/llvm/bindings.zig+1-4
...@@ -330,10 +330,7 @@ pub const Value = opaque {...@@ -330,10 +330,7 @@ pub const Value = opaque {
330 pub const fnSetSubprogram = ZigLLVMFnSetSubprogram;330 pub const fnSetSubprogram = ZigLLVMFnSetSubprogram;
331 extern fn ZigLLVMFnSetSubprogram(f: *Value, subprogram: *DISubprogram) void;331 extern fn ZigLLVMFnSetSubprogram(f: *Value, subprogram: *DISubprogram) void;
332332
333 pub const setValueName = LLVMSetValueName;333 pub const setValueName = LLVMSetValueName2;
334 extern fn LLVMSetValueName(Val: *Value, Name: [*:0]const u8) void;
335
336 pub const setValueName2 = LLVMSetValueName2;
337 extern fn LLVMSetValueName2(Val: *Value, Name: [*]const u8, NameLen: usize) void;334 extern fn LLVMSetValueName2(Val: *Value, Name: [*]const u8, NameLen: usize) void;
338335
339 pub const getValueName = LLVMGetValueName;336 pub const getValueName = LLVMGetValueName;
src/zig_llvm.cpp+2-2
...@@ -1123,11 +1123,11 @@ void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim) {...@@ -1123,11 +1123,11 @@ void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim) {
1123}1123}
11241124
1125ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression) {1125ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
1126 return reinterpret_cast<ZigLLVMDIGlobalVariable*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getVariable());1126 return reinterpret_cast<ZigLLVMDIGlobalVariable*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getVariable());
1127}1127}
11281128
1129void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression) {1129void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
1130 unwrap<GlobalVariable>(Val)->addDebugInfo(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression));1130 unwrap<GlobalVariable>(Val)->addDebugInfo(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression));
1131}1131}
11321132
1133static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, "");1133static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, "");