authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-06 07:16:39-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-08 21:32:50-04:00
logb63d9745b5d7413acea4f4723ac9f696e3fb8149
tree079fb983319924b73f09fe17d0c757e252b009b7
parent3ebf8ce9704647686a9f9654c59e0be17bc78984

llvm: convert intrinsics to using `Builder`


5 files changed, 1260 insertions(+), 1371 deletions(-)

src/codegen/llvm.zig+225-475
......@@ -4962,9 +4962,9 @@ pub const FuncGen = struct {
49624962 .mul_wrap => try self.airMulWrap(inst),
49634963 .mul_sat => try self.airMulSat(inst),
49644964
4965 .add_safe => try self.airSafeArithmetic(inst, "llvm.sadd.with.overflow", "llvm.uadd.with.overflow"),
4966 .sub_safe => try self.airSafeArithmetic(inst, "llvm.ssub.with.overflow", "llvm.usub.with.overflow"),
4967 .mul_safe => try self.airSafeArithmetic(inst, "llvm.smul.with.overflow", "llvm.umul.with.overflow"),
4965 .add_safe => try self.airSafeArithmetic(inst, .@"sadd.with.overflow", .@"uadd.with.overflow"),
4966 .sub_safe => try self.airSafeArithmetic(inst, .@"ssub.with.overflow", .@"usub.with.overflow"),
4967 .mul_safe => try self.airSafeArithmetic(inst, .@"smul.with.overflow", .@"umul.with.overflow"),
49684968
49694969 .div_float => try self.airDivFloat(inst, false),
49704970 .div_trunc => try self.airDivTrunc(inst, false),
......@@ -4989,9 +4989,9 @@ pub const FuncGen = struct {
49894989 .rem_optimized => try self.airRem(inst, true),
49904990 .mod_optimized => try self.airMod(inst, true),
49914991
4992 .add_with_overflow => try self.airOverflow(inst, "llvm.sadd.with.overflow", "llvm.uadd.with.overflow"),
4993 .sub_with_overflow => try self.airOverflow(inst, "llvm.ssub.with.overflow", "llvm.usub.with.overflow"),
4994 .mul_with_overflow => try self.airOverflow(inst, "llvm.smul.with.overflow", "llvm.umul.with.overflow"),
4992 .add_with_overflow => try self.airOverflow(inst, .@"sadd.with.overflow", .@"uadd.with.overflow"),
4993 .sub_with_overflow => try self.airOverflow(inst, .@"ssub.with.overflow", .@"usub.with.overflow"),
4994 .mul_with_overflow => try self.airOverflow(inst, .@"smul.with.overflow", .@"umul.with.overflow"),
49954995 .shl_with_overflow => try self.airShlWithOverflow(inst),
49964996
49974997 .bit_and, .bool_and => try self.airAnd(inst),
......@@ -5100,11 +5100,11 @@ pub const FuncGen = struct {
51005100 .memcpy => try self.airMemcpy(inst),
51015101 .set_union_tag => try self.airSetUnionTag(inst),
51025102 .get_union_tag => try self.airGetUnionTag(inst),
5103 .clz => try self.airClzCtz(inst, .@"llvm.ctlz."),
5104 .ctz => try self.airClzCtz(inst, .@"llvm.cttz."),
5105 .popcount => try self.airBitOp(inst, .@"llvm.ctpop."),
5103 .clz => try self.airClzCtz(inst, .ctlz),
5104 .ctz => try self.airClzCtz(inst, .cttz),
5105 .popcount => try self.airBitOp(inst, .ctpop),
51065106 .byte_swap => try self.airByteSwap(inst),
5107 .bit_reverse => try self.airBitOp(inst, .@"llvm.bitreverse."),
5107 .bit_reverse => try self.airBitOp(inst, .bitreverse),
51085108 .tag_name => try self.airTagName(inst),
51095109 .error_name => try self.airErrorName(inst),
51105110 .splat => try self.airSplat(inst),
......@@ -5645,22 +5645,7 @@ pub const FuncGen = struct {
56455645 const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod));
56465646 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
56475647
5648 const llvm_fn_name = "llvm.va_copy";
5649 const llvm_fn_ty = try o.builder.fnType(.void, &.{ .ptr, .ptr }, .normal);
5650 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse
5651 o.llvm_module.addFunction(llvm_fn_name, llvm_fn_ty.toLlvm(&o.builder));
5652
5653 const args: [2]*llvm.Value = .{ dest_list.toLlvm(&self.wip), src_list.toLlvm(&self.wip) };
5654 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildCallOld(
5655 llvm_fn_ty.toLlvm(&o.builder),
5656 llvm_fn,
5657 &args,
5658 args.len,
5659 .Fast,
5660 .Auto,
5661 "",
5662 ), &self.wip);
5663
5648 _ = try self.wip.callIntrinsic(.va_copy, &.{}, &.{ dest_list, src_list }, "");
56645649 return if (isByRef(va_list_ty, mod))
56655650 dest_list
56665651 else
......@@ -5668,25 +5653,10 @@ pub const FuncGen = struct {
56685653 }
56695654
56705655 fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5671 const o = self.dg.object;
56725656 const un_op = self.air.instructions.items(.data)[inst].un_op;
5673 const list = try self.resolveInst(un_op);
5674
5675 const llvm_fn_name = "llvm.va_end";
5676 const llvm_fn_ty = try o.builder.fnType(.void, &.{.ptr}, .normal);
5677 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse
5678 o.llvm_module.addFunction(llvm_fn_name, llvm_fn_ty.toLlvm(&o.builder));
5657 const src_list = try self.resolveInst(un_op);
56795658
5680 const args: [1]*llvm.Value = .{list.toLlvm(&self.wip)};
5681 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildCallOld(
5682 llvm_fn_ty.toLlvm(&o.builder),
5683 llvm_fn,
5684 &args,
5685 args.len,
5686 .Fast,
5687 .Auto,
5688 "",
5689 ), &self.wip);
5659 _ = try self.wip.callIntrinsic(.va_end, &.{}, &.{src_list}, "");
56905660 return .none;
56915661 }
56925662
......@@ -5697,28 +5667,13 @@ pub const FuncGen = struct {
56975667 const llvm_va_list_ty = try o.lowerType(va_list_ty);
56985668
56995669 const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod));
5700 const list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
5701
5702 const llvm_fn_name = "llvm.va_start";
5703 const llvm_fn_ty = try o.builder.fnType(.void, &.{.ptr}, .normal);
5704 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse
5705 o.llvm_module.addFunction(llvm_fn_name, llvm_fn_ty.toLlvm(&o.builder));
5706
5707 const args: [1]*llvm.Value = .{list.toLlvm(&self.wip)};
5708 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildCallOld(
5709 llvm_fn_ty.toLlvm(&o.builder),
5710 llvm_fn,
5711 &args,
5712 args.len,
5713 .Fast,
5714 .Auto,
5715 "",
5716 ), &self.wip);
5670 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
57175671
5672 _ = try self.wip.callIntrinsic(.va_start, &.{}, &.{dest_list}, "");
57185673 return if (isByRef(va_list_ty, mod))
5719 list
5674 dest_list
57205675 else
5721 try self.wip.load(.normal, llvm_va_list_ty, list, result_alignment, "");
5676 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");
57225677 }
57235678
57245679 fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator, want_fast_math: bool) !Builder.Value {
......@@ -7570,40 +7525,18 @@ pub const FuncGen = struct {
75707525 const o = self.dg.object;
75717526 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
75727527 const index = pl_op.payload;
7573 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.size", &.{.i32});
7574 const args: [1]*llvm.Value = .{
7575 (try o.builder.intConst(.i32, index)).toLlvm(&o.builder),
7576 };
7577 return (try self.wip.unimplemented(.i32, "")).finish(self.builder.buildCallOld(
7578 (try o.builder.fnType(.i32, &.{.i32}, .normal)).toLlvm(&o.builder),
7579 llvm_fn,
7580 &args,
7581 args.len,
7582 .Fast,
7583 .Auto,
7584 "",
7585 ), &self.wip);
7528 return self.wip.callIntrinsic(.@"wasm.memory.size", &.{.i32}, &.{
7529 try o.builder.intValue(.i32, index),
7530 }, "");
75867531 }
75877532
75887533 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
75897534 const o = self.dg.object;
75907535 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
75917536 const index = pl_op.payload;
7592 const operand = try self.resolveInst(pl_op.operand);
7593 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.grow", &.{.i32});
7594 const args: [2]*llvm.Value = .{
7595 (try o.builder.intConst(.i32, index)).toLlvm(&o.builder),
7596 operand.toLlvm(&self.wip),
7597 };
7598 return (try self.wip.unimplemented(.i32, "")).finish(self.builder.buildCallOld(
7599 (try o.builder.fnType(.i32, &.{ .i32, .i32 }, .normal)).toLlvm(&o.builder),
7600 llvm_fn,
7601 &args,
7602 args.len,
7603 .Fast,
7604 .Auto,
7605 "",
7606 ), &self.wip);
7537 return self.wip.callIntrinsic(.@"wasm.memory.grow", &.{.i32}, &.{
7538 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),
7539 }, "");
76077540 }
76087541
76097542 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -7636,13 +7569,16 @@ pub const FuncGen = struct {
76367569 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76377570 const lhs = try self.resolveInst(bin_op.lhs);
76387571 const rhs = try self.resolveInst(bin_op.rhs);
7639 const scalar_ty = self.typeOfIndex(inst).scalarType(mod);
7572 const inst_ty = self.typeOfIndex(inst);
7573 const scalar_ty = inst_ty.scalarType(mod);
76407574
7641 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });
7642 return self.wip.bin(if (scalar_ty.isSignedInt(mod))
7643 .@"llvm.smin."
7644 else
7645 .@"llvm.umin.", lhs, rhs, "");
7575 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, inst_ty, 2, .{ lhs, rhs });
7576 return self.wip.callIntrinsic(
7577 if (scalar_ty.isSignedInt(mod)) .smin else .umin,
7578 &.{try o.lowerType(inst_ty)},
7579 &.{ lhs, rhs },
7580 "",
7581 );
76467582 }
76477583
76487584 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -7651,13 +7587,16 @@ pub const FuncGen = struct {
76517587 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
76527588 const lhs = try self.resolveInst(bin_op.lhs);
76537589 const rhs = try self.resolveInst(bin_op.rhs);
7654 const scalar_ty = self.typeOfIndex(inst).scalarType(mod);
7590 const inst_ty = self.typeOfIndex(inst);
7591 const scalar_ty = inst_ty.scalarType(mod);
76557592
7656 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });
7657 return self.wip.bin(if (scalar_ty.isSignedInt(mod))
7658 .@"llvm.smax."
7659 else
7660 .@"llvm.umax.", lhs, rhs, "");
7593 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, inst_ty, 2, .{ lhs, rhs });
7594 return self.wip.callIntrinsic(
7595 if (scalar_ty.isSignedInt(mod)) .smax else .umax,
7596 &.{try o.lowerType(inst_ty)},
7597 &.{ lhs, rhs },
7598 "",
7599 );
76617600 }
76627601
76637602 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -7688,8 +7627,8 @@ pub const FuncGen = struct {
76887627 fn airSafeArithmetic(
76897628 fg: *FuncGen,
76907629 inst: Air.Inst.Index,
7691 signed_intrinsic: []const u8,
7692 unsigned_intrinsic: []const u8,
7630 signed_intrinsic: Builder.Intrinsic,
7631 unsigned_intrinsic: Builder.Intrinsic,
76937632 ) !Builder.Value {
76947633 const o = fg.dg.object;
76957634 const mod = o.module;
......@@ -7699,36 +7638,19 @@ pub const FuncGen = struct {
76997638 const rhs = try fg.resolveInst(bin_op.rhs);
77007639 const inst_ty = fg.typeOfIndex(inst);
77017640 const scalar_ty = inst_ty.scalarType(mod);
7702 const is_scalar = scalar_ty.ip_index == inst_ty.ip_index;
77037641
7704 const intrinsic_name = switch (scalar_ty.isSignedInt(mod)) {
7705 true => signed_intrinsic,
7706 false => unsigned_intrinsic,
7707 };
7642 const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
77087643 const llvm_inst_ty = try o.lowerType(inst_ty);
7709 const llvm_ret_ty = try o.builder.structType(.normal, &.{
7710 llvm_inst_ty,
7711 try llvm_inst_ty.changeScalar(.i1, &o.builder),
7712 });
7713 const llvm_fn_ty = try o.builder.fnType(llvm_ret_ty, &.{ llvm_inst_ty, llvm_inst_ty }, .normal);
7714 const llvm_fn = try fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty});
7715 const result_struct = (try fg.wip.unimplemented(llvm_ret_ty, "")).finish(fg.builder.buildCallOld(
7716 llvm_fn_ty.toLlvm(&o.builder),
7717 llvm_fn,
7718 &[_]*llvm.Value{ lhs.toLlvm(&fg.wip), rhs.toLlvm(&fg.wip) },
7719 2,
7720 .Fast,
7721 .Auto,
7722 "",
7723 ), &fg.wip);
7724 const overflow_bit = try fg.wip.extractValue(result_struct, &.{1}, "");
7725 const scalar_overflow_bit = switch (is_scalar) {
7726 true => overflow_bit,
7727 false => (try fg.wip.unimplemented(.i1, "")).finish(
7644 const results = try fg.wip.callIntrinsic(intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");
7645
7646 const overflow_bit = try fg.wip.extractValue(results, &.{1}, "");
7647 const scalar_overflow_bit = if (llvm_inst_ty.isVector(&o.builder))
7648 (try fg.wip.unimplemented(.i1, "")).finish(
77287649 fg.builder.buildOrReduce(overflow_bit.toLlvm(&fg.wip)),
77297650 &fg.wip,
7730 ),
7731 };
7651 )
7652 else
7653 overflow_bit;
77327654
77337655 const fail_block = try fg.wip.block(1, "OverflowFail");
77347656 const ok_block = try fg.wip.block(1, "OverflowOk");
......@@ -7738,7 +7660,7 @@ pub const FuncGen = struct {
77387660 try fg.buildSimplePanic(.integer_overflow);
77397661
77407662 fg.wip.cursor = .{ .block = ok_block };
7741 return fg.wip.extractValue(result_struct, &.{0}, "");
7663 return fg.wip.extractValue(results, &.{0}, "");
77427664 }
77437665
77447666 fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -7759,10 +7681,12 @@ pub const FuncGen = struct {
77597681 const scalar_ty = inst_ty.scalarType(mod);
77607682
77617683 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});
7762 return self.wip.bin(if (scalar_ty.isSignedInt(mod))
7763 .@"llvm.sadd.sat."
7764 else
7765 .@"llvm.uadd.sat.", lhs, rhs, "");
7684 return self.wip.callIntrinsic(
7685 if (scalar_ty.isSignedInt(mod)) .@"sadd.sat" else .@"uadd.sat",
7686 &.{try o.lowerType(inst_ty)},
7687 &.{ lhs, rhs },
7688 "",
7689 );
77667690 }
77677691
77687692 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !Builder.Value {
......@@ -7798,10 +7722,12 @@ pub const FuncGen = struct {
77987722 const scalar_ty = inst_ty.scalarType(mod);
77997723
78007724 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
7801 return self.wip.bin(if (scalar_ty.isSignedInt(mod))
7802 .@"llvm.ssub.sat."
7803 else
7804 .@"llvm.usub.sat.", lhs, rhs, "");
7725 return self.wip.callIntrinsic(
7726 if (scalar_ty.isSignedInt(mod)) .@"ssub.sat" else .@"usub.sat",
7727 &.{try o.lowerType(inst_ty)},
7728 &.{ lhs, rhs },
7729 "",
7730 );
78057731 }
78067732
78077733 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !Builder.Value {
......@@ -7837,10 +7763,12 @@ pub const FuncGen = struct {
78377763 const scalar_ty = inst_ty.scalarType(mod);
78387764
78397765 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
7840 return self.wip.bin(if (scalar_ty.isSignedInt(mod))
7841 .@"llvm.smul.fix.sat."
7842 else
7843 .@"llvm.umul.fix.sat.", lhs, rhs, "");
7766 return self.wip.callIntrinsic(
7767 if (scalar_ty.isSignedInt(mod)) .@"smul.fix.sat" else .@"umul.fix.sat",
7768 &.{try o.lowerType(inst_ty)},
7769 &.{ lhs, rhs, try o.builder.intValue(.i32, 0) },
7770 "",
7771 );
78447772 }
78457773
78467774 fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !Builder.Value {
......@@ -8028,8 +7956,8 @@ pub const FuncGen = struct {
80287956 fn airOverflow(
80297957 self: *FuncGen,
80307958 inst: Air.Inst.Index,
8031 signed_intrinsic: []const u8,
8032 unsigned_intrinsic: []const u8,
7959 signed_intrinsic: Builder.Intrinsic,
7960 unsigned_intrinsic: Builder.Intrinsic,
80337961 ) !Builder.Value {
80347962 const o = self.dg.object;
80357963 const mod = o.module;
......@@ -8041,48 +7969,29 @@ pub const FuncGen = struct {
80417969
80427970 const lhs_ty = self.typeOf(extra.lhs);
80437971 const scalar_ty = lhs_ty.scalarType(mod);
8044 const dest_ty = self.typeOfIndex(inst);
8045
8046 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
7972 const inst_ty = self.typeOfIndex(inst);
80477973
8048 const llvm_dest_ty = try o.lowerType(dest_ty);
7974 const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
7975 const llvm_inst_ty = try o.lowerType(inst_ty);
80497976 const llvm_lhs_ty = try o.lowerType(lhs_ty);
7977 const results = try self.wip.callIntrinsic(intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");
80507978
8051 const llvm_fn = try self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
8052 const llvm_ret_ty = try o.builder.structType(
8053 .normal,
8054 &.{ llvm_lhs_ty, try llvm_lhs_ty.changeScalar(.i1, &o.builder) },
8055 );
8056 const llvm_fn_ty = try o.builder.fnType(llvm_ret_ty, &.{ llvm_lhs_ty, llvm_lhs_ty }, .normal);
8057 const result_struct = (try self.wip.unimplemented(llvm_ret_ty, "")).finish(
8058 self.builder.buildCallOld(
8059 llvm_fn_ty.toLlvm(&o.builder),
8060 llvm_fn,
8061 &[_]*llvm.Value{ lhs.toLlvm(&self.wip), rhs.toLlvm(&self.wip) },
8062 2,
8063 .Fast,
8064 .Auto,
8065 "",
8066 ),
8067 &self.wip,
8068 );
8069
8070 const result = try self.wip.extractValue(result_struct, &.{0}, "");
8071 const overflow_bit = try self.wip.extractValue(result_struct, &.{1}, "");
7979 const result_val = try self.wip.extractValue(results, &.{0}, "");
7980 const overflow_bit = try self.wip.extractValue(results, &.{1}, "");
80727981
8073 const result_index = llvmField(dest_ty, 0, mod).?.index;
8074 const overflow_index = llvmField(dest_ty, 1, mod).?.index;
7982 const result_index = llvmField(inst_ty, 0, mod).?.index;
7983 const overflow_index = llvmField(inst_ty, 1, mod).?.index;
80757984
8076 if (isByRef(dest_ty, mod)) {
8077 const result_alignment = Builder.Alignment.fromByteUnits(dest_ty.abiAlignment(mod));
8078 const alloca_inst = try self.buildAlloca(llvm_dest_ty, result_alignment);
7985 if (isByRef(inst_ty, mod)) {
7986 const result_alignment = Builder.Alignment.fromByteUnits(inst_ty.abiAlignment(mod));
7987 const alloca_inst = try self.buildAlloca(llvm_inst_ty, result_alignment);
80797988 {
8080 const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, result_index, "");
8081 _ = try self.wip.store(.normal, result, field_ptr, result_alignment);
7989 const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, result_index, "");
7990 _ = try self.wip.store(.normal, result_val, field_ptr, result_alignment);
80827991 }
80837992 {
80847993 const overflow_alignment = comptime Builder.Alignment.fromByteUnits(1);
8085 const field_ptr = try self.wip.gepStruct(llvm_dest_ty, alloca_inst, overflow_index, "");
7994 const field_ptr = try self.wip.gepStruct(llvm_inst_ty, alloca_inst, overflow_index, "");
80867995 _ = try self.wip.store(.normal, overflow_bit, field_ptr, overflow_alignment);
80877996 }
80887997
......@@ -8090,9 +7999,9 @@ pub const FuncGen = struct {
80907999 }
80918000
80928001 var fields: [2]Builder.Value = undefined;
8093 fields[result_index] = result;
8002 fields[result_index] = result_val;
80948003 fields[overflow_index] = overflow_bit;
8095 return self.wip.buildAggregate(llvm_dest_ty, &fields, "");
8004 return self.wip.buildAggregate(llvm_inst_ty, &fields, "");
80968005 }
80978006
80988007 fn buildElementwiseCall(
......@@ -8140,22 +8049,7 @@ pub const FuncGen = struct {
81408049 .function => |function| function,
81418050 else => unreachable,
81428051 };
8143
8144 const fn_type = try o.builder.fnType(return_type, param_types, .normal);
8145 const f = o.llvm_module.addFunction(fn_name.slice(&o.builder).?, fn_type.toLlvm(&o.builder));
8146
8147 var global = Builder.Global{
8148 .type = fn_type,
8149 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
8150 };
8151 var function = Builder.Function{
8152 .global = @enumFromInt(o.builder.globals.count()),
8153 };
8154
8155 try o.builder.llvm.globals.append(self.gpa, f);
8156 _ = try o.builder.addGlobal(fn_name, global);
8157 try o.builder.functions.append(self.gpa, function);
8158 return global.kind.function;
8052 return o.builder.addFunction(try o.builder.fnType(return_type, param_types, .normal), fn_name);
81598053 }
81608054
81618055 /// Creates a floating point comparison by lowering to the appropriate
......@@ -8290,22 +8184,22 @@ pub const FuncGen = struct {
82908184 .mul => return self.wip.bin(.fmul, params[0], params[1], ""),
82918185 .div => return self.wip.bin(.fdiv, params[0], params[1], ""),
82928186 .fmod => return self.wip.bin(.frem, params[0], params[1], ""),
8293 .fmax => return self.wip.bin(.@"llvm.maxnum.", params[0], params[1], ""),
8294 .fmin => return self.wip.bin(.@"llvm.minnum.", params[0], params[1], ""),
8295 .ceil => return self.wip.un(.@"llvm.ceil.", params[0], ""),
8296 .cos => return self.wip.un(.@"llvm.cos.", params[0], ""),
8297 .exp => return self.wip.un(.@"llvm.exp.", params[0], ""),
8298 .exp2 => return self.wip.un(.@"llvm.exp2.", params[0], ""),
8299 .fabs => return self.wip.un(.@"llvm.fabs.", params[0], ""),
8300 .floor => return self.wip.un(.@"llvm.floor.", params[0], ""),
8301 .log => return self.wip.un(.@"llvm.log.", params[0], ""),
8302 .log10 => return self.wip.un(.@"llvm.log10.", params[0], ""),
8303 .log2 => return self.wip.un(.@"llvm.log2.", params[0], ""),
8304 .round => return self.wip.un(.@"llvm.round.", params[0], ""),
8305 .sin => return self.wip.un(.@"llvm.sin.", params[0], ""),
8306 .sqrt => return self.wip.un(.@"llvm.sqrt.", params[0], ""),
8307 .trunc => return self.wip.un(.@"llvm.trunc.", params[0], ""),
8308 .fma => return self.wip.fusedMultiplyAdd(params[0], params[1], params[2]),
8187 .fmax => return self.wip.callIntrinsic(.maxnum, &.{llvm_ty}, &params, ""),
8188 .fmin => return self.wip.callIntrinsic(.minnum, &.{llvm_ty}, &params, ""),
8189 .ceil => return self.wip.callIntrinsic(.ceil, &.{llvm_ty}, &params, ""),
8190 .cos => return self.wip.callIntrinsic(.cos, &.{llvm_ty}, &params, ""),
8191 .exp => return self.wip.callIntrinsic(.exp, &.{llvm_ty}, &params, ""),
8192 .exp2 => return self.wip.callIntrinsic(.exp2, &.{llvm_ty}, &params, ""),
8193 .fabs => return self.wip.callIntrinsic(.fabs, &.{llvm_ty}, &params, ""),
8194 .floor => return self.wip.callIntrinsic(.floor, &.{llvm_ty}, &params, ""),
8195 .log => return self.wip.callIntrinsic(.log, &.{llvm_ty}, &params, ""),
8196 .log10 => return self.wip.callIntrinsic(.log10, &.{llvm_ty}, &params, ""),
8197 .log2 => return self.wip.callIntrinsic(.log2, &.{llvm_ty}, &params, ""),
8198 .round => return self.wip.callIntrinsic(.round, &.{llvm_ty}, &params, ""),
8199 .sin => return self.wip.callIntrinsic(.sin, &.{llvm_ty}, &params, ""),
8200 .sqrt => return self.wip.callIntrinsic(.sqrt, &.{llvm_ty}, &params, ""),
8201 .trunc => return self.wip.callIntrinsic(.trunc, &.{llvm_ty}, &params, ""),
8202 .fma => return self.wip.callIntrinsic(.fma, &.{llvm_ty}, &params, ""),
83098203 .tan => unreachable,
83108204 };
83118205
......@@ -8499,25 +8393,27 @@ pub const FuncGen = struct {
84998393
85008394 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), "");
85018395
8502 const result = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(mod))
8503 .@"llvm.sshl.sat."
8504 else
8505 .@"llvm.ushl.sat.", lhs, casted_rhs, "");
8396 const llvm_lhs_ty = try o.lowerType(lhs_ty);
8397 const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder);
8398 const result = try self.wip.callIntrinsic(
8399 if (lhs_scalar_ty.isSignedInt(mod)) .@"sshl.sat" else .@"ushl.sat",
8400 &.{llvm_lhs_ty},
8401 &.{ lhs, casted_rhs },
8402 "",
8403 );
85068404
85078405 // LLVM langref says "If b is (statically or dynamically) equal to or
85088406 // larger than the integer bit width of the arguments, the result is a
85098407 // poison value."
85108408 // However Zig semantics says that saturating shift left can never produce
85118409 // undefined; instead it saturates.
8512 const lhs_llvm_ty = try o.lowerType(lhs_ty);
8513 const lhs_scalar_llvm_ty = lhs_llvm_ty.scalarType(&o.builder);
85148410 const bits = try o.builder.splatValue(
8515 lhs_llvm_ty,
8516 try o.builder.intConst(lhs_scalar_llvm_ty, lhs_bits),
8411 llvm_lhs_ty,
8412 try o.builder.intConst(llvm_lhs_scalar_ty, lhs_bits),
85178413 );
85188414 const lhs_max = try o.builder.splatValue(
8519 lhs_llvm_ty,
8520 try o.builder.intConst(lhs_scalar_llvm_ty, -1),
8415 llvm_lhs_ty,
8416 try o.builder.intConst(llvm_lhs_scalar_ty, -1),
85218417 );
85228418 const in_range = try self.wip.icmp(.ult, rhs, bits, "");
85238419 return self.wip.select(in_range, result, lhs_max, "");
......@@ -8940,90 +8836,38 @@ pub const FuncGen = struct {
89408836
89418837 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
89428838 _ = inst;
8943 const o = self.dg.object;
8944 const llvm_fn = try self.getIntrinsic("llvm.trap", &.{});
8945 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildCallOld(
8946 (try o.builder.fnType(.void, &.{}, .normal)).toLlvm(&o.builder),
8947 llvm_fn,
8948 undefined,
8949 0,
8950 .Cold,
8951 .Auto,
8952 "",
8953 ), &self.wip);
8839 _ = try self.wip.callIntrinsic(.trap, &.{}, &.{}, "");
89548840 _ = try self.wip.@"unreachable"();
89558841 return .none;
89568842 }
89578843
89588844 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
89598845 _ = inst;
8960 const o = self.dg.object;
8961 const llvm_fn = try self.getIntrinsic("llvm.debugtrap", &.{});
8962 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildCallOld(
8963 (try o.builder.fnType(.void, &.{}, .normal)).toLlvm(&o.builder),
8964 llvm_fn,
8965 undefined,
8966 0,
8967 .C,
8968 .Auto,
8969 "",
8970 ), &self.wip);
8846 _ = try self.wip.callIntrinsic(.debugtrap, &.{}, &.{}, "");
89718847 return .none;
89728848 }
89738849
89748850 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
89758851 _ = inst;
89768852 const o = self.dg.object;
8977 const mod = o.module;
89788853 const llvm_usize = try o.lowerType(Type.usize);
8979 const target = mod.getTarget();
8980 if (!target_util.supportsReturnAddress(target)) {
8854 if (!target_util.supportsReturnAddress(o.module.getTarget())) {
89818855 // https://github.com/ziglang/zig/issues/11946
89828856 return o.builder.intValue(llvm_usize, 0);
89838857 }
8984
8985 const llvm_fn = try self.getIntrinsic("llvm.returnaddress", &.{});
8986 const params = [_]*llvm.Value{
8987 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
8988 };
8989 const ptr_val = (try self.wip.unimplemented(.ptr, "")).finish(self.builder.buildCallOld(
8990 (try o.builder.fnType(.ptr, &.{.i32}, .normal)).toLlvm(&o.builder),
8991 llvm_fn,
8992 &params,
8993 params.len,
8994 .Fast,
8995 .Auto,
8996 "",
8997 ), &self.wip);
8998 return self.wip.cast(.ptrtoint, ptr_val, llvm_usize, "");
8858 const result = try self.wip.callIntrinsic(.returnaddress, &.{}, &.{
8859 try o.builder.intValue(.i32, 0),
8860 }, "");
8861 return self.wip.cast(.ptrtoint, result, llvm_usize, "");
89998862 }
90008863
90018864 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
90028865 _ = inst;
90038866 const o = self.dg.object;
9004 const llvm_fn_name = "llvm.frameaddress.p0";
9005 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
9006 const fn_type = try o.builder.fnType(.ptr, &.{.i32}, .normal);
9007 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
9008 };
9009 const llvm_fn_ty = try o.builder.fnType(.ptr, &.{.i32}, .normal);
9010
9011 const params = [_]*llvm.Value{
9012 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
9013 };
9014 const ptr_val = (try self.wip.unimplemented(llvm_fn_ty.functionReturn(&o.builder), "")).finish(
9015 self.builder.buildCallOld(
9016 llvm_fn_ty.toLlvm(&o.builder),
9017 llvm_fn,
9018 &params,
9019 params.len,
9020 .Fast,
9021 .Auto,
9022 "",
9023 ),
9024 &self.wip,
9025 );
9026 return self.wip.cast(.ptrtoint, ptr_val, try o.lowerType(Type.usize), "");
8867 const result = try self.wip.callIntrinsic(.frameaddress, &.{.ptr}, &.{
8868 try o.builder.intValue(.i32, 0),
8869 }, "");
8870 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");
90278871 }
90288872
90298873 fn airFence(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -9526,26 +9370,37 @@ pub const FuncGen = struct {
95269370 return self.buildFloatOp(.neg, operand_ty, 1, .{operand});
95279371 }
95289372
9529 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Function.Instruction.Tag) !Builder.Value {
9373 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {
95309374 const o = self.dg.object;
95319375 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9376 const inst_ty = self.typeOfIndex(inst);
9377 const operand_ty = self.typeOf(ty_op.operand);
95329378 const operand = try self.resolveInst(ty_op.operand);
95339379
9534 const wrong_size_result = try self.wip.bin(intrinsic, operand, (try o.builder.intConst(.i1, 0)).toValue(), "");
9535
9536 const result_ty = self.typeOfIndex(inst);
9537 return self.wip.conv(.unsigned, wrong_size_result, try o.lowerType(result_ty), "");
9380 const result =
9381 try self.wip.callIntrinsic(
9382 intrinsic,
9383 &.{try o.lowerType(operand_ty)},
9384 &.{ operand, .false },
9385 "",
9386 );
9387 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty), "");
95389388 }
95399389
9540 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Function.Instruction.Tag) !Builder.Value {
9390 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {
95419391 const o = self.dg.object;
95429392 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9393 const inst_ty = self.typeOfIndex(inst);
9394 const operand_ty = self.typeOf(ty_op.operand);
95439395 const operand = try self.resolveInst(ty_op.operand);
95449396
9545 const wrong_size_result = try self.wip.un(intrinsic, operand, "");
9546
9547 const result_ty = self.typeOfIndex(inst);
9548 return self.wip.conv(.unsigned, wrong_size_result, try o.lowerType(result_ty), "");
9397 const result = try self.wip.callIntrinsic(
9398 intrinsic,
9399 &.{try o.lowerType(operand_ty)},
9400 &.{operand},
9401 "",
9402 );
9403 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty), "");
95499404 }
95509405
95519406 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -9556,6 +9411,7 @@ pub const FuncGen = struct {
95569411 var bits = operand_ty.intInfo(mod).bits;
95579412 assert(bits % 8 == 0);
95589413
9414 const inst_ty = self.typeOfIndex(inst);
95599415 var operand = try self.resolveInst(ty_op.operand);
95609416 var llvm_operand_ty = try o.lowerType(operand_ty);
95619417
......@@ -9576,10 +9432,8 @@ pub const FuncGen = struct {
95769432 bits = bits + 8;
95779433 }
95789434
9579 const wrong_size_result = try self.wip.un(.@"llvm.bswap.", operand, "");
9580
9581 const result_ty = self.typeOfIndex(inst);
9582 return self.wip.conv(.unsigned, wrong_size_result, try o.lowerType(result_ty), "");
9435 const result = try self.wip.callIntrinsic(.bswap, &.{llvm_operand_ty}, &.{operand}, "");
9436 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty), "");
95839437 }
95849438
95859439 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -9609,11 +9463,7 @@ pub const FuncGen = struct {
96099463
96109464 self.wip.cursor = .{ .block = end_block };
96119465 const phi = try self.wip.phi(.i1, "");
9612 try phi.finish(
9613 &.{ Builder.Constant.true.toValue(), Builder.Constant.false.toValue() },
9614 &.{ valid_block, invalid_block },
9615 &self.wip,
9616 );
9466 try phi.finish(&.{ .true, .false }, &.{ valid_block, invalid_block }, &self.wip);
96179467 return phi.toValue();
96189468 }
96199469
......@@ -9646,37 +9496,24 @@ pub const FuncGen = struct {
96469496 errdefer assert(o.named_enum_map.remove(enum_type.decl));
96479497
96489498 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9649 const llvm_fn_name = try o.builder.fmt("__zig_is_named_enum_value_{}", .{
9650 fqn.fmt(&mod.intern_pool),
9651 });
9499 const function_index = try o.builder.addFunction(
9500 try o.builder.fnType(.i1, &.{try o.lowerType(enum_type.tag_ty.toType())}, .normal),
9501 try o.builder.fmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}),
9502 );
96529503
96539504 var attributes: Builder.FunctionAttributes.Wip = .{};
96549505 defer attributes.deinit(&o.builder);
96559506
9656 const fn_type = try o.builder.fnType(.i1, &.{
9657 try o.lowerType(enum_type.tag_ty.toType()),
9658 }, .normal);
9659 const fn_val = o.llvm_module.addFunction(llvm_fn_name.slice(&o.builder).?, fn_type.toLlvm(&o.builder));
9660 fn_val.setLinkage(.Internal);
9661 fn_val.setFunctionCallConv(.Fast);
9662 try o.addCommonFnAttributes(&attributes, fn_val);
9507 function_index.toLlvm(&o.builder).setLinkage(.Internal);
9508 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9509 try o.addCommonFnAttributes(&attributes, function_index.toLlvm(&o.builder));
96639510
9664 var global = Builder.Global{
9665 .linkage = .internal,
9666 .type = fn_type,
9667 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9668 };
9669 var function = Builder.Function{
9670 .global = @enumFromInt(o.builder.globals.count()),
9671 .call_conv = .fastcc,
9672 .attributes = try attributes.finish(&o.builder),
9673 };
9674 try o.builder.llvm.globals.append(self.gpa, fn_val);
9675 _ = try o.builder.addGlobal(llvm_fn_name, global);
9676 try o.builder.functions.append(self.gpa, function);
9677 gop.value_ptr.* = global.kind.function;
9511 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;
9512 function_index.ptr(&o.builder).call_conv = .fastcc;
9513 function_index.ptr(&o.builder).attributes = try attributes.finish(&o.builder);
9514 gop.value_ptr.* = function_index;
96789515
9679 var wip = try Builder.WipFunction.init(&o.builder, global.kind.function);
9516 var wip = try Builder.WipFunction.init(&o.builder, function_index);
96809517 defer wip.deinit();
96819518 wip.cursor = .{ .block = try wip.block(0, "Entry") };
96829519
......@@ -9693,13 +9530,13 @@ pub const FuncGen = struct {
96939530 try wip_switch.addCase(this_tag_int_value, named_block, &wip);
96949531 }
96959532 wip.cursor = .{ .block = named_block };
9696 _ = try wip.ret(Builder.Constant.true.toValue());
9533 _ = try wip.ret(.true);
96979534
96989535 wip.cursor = .{ .block = unnamed_block };
9699 _ = try wip.ret(Builder.Constant.false.toValue());
9536 _ = try wip.ret(.false);
97009537
97019538 try wip.finish();
9702 return global.kind.function;
9539 return function_index;
97039540 }
97049541
97059542 fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -9730,38 +9567,27 @@ pub const FuncGen = struct {
97309567 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;
97319568 errdefer assert(o.decl_map.remove(enum_type.decl));
97329569
9570 const usize_ty = try o.lowerType(Type.usize);
9571 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
97339572 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9734 const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
9573 const function_index = try o.builder.addFunction(
9574 try o.builder.fnType(ret_ty, &.{try o.lowerType(enum_type.tag_ty.toType())}, .normal),
9575 try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)}),
9576 );
97359577
97369578 var attributes: Builder.FunctionAttributes.Wip = .{};
97379579 defer attributes.deinit(&o.builder);
97389580
9739 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
9740 const usize_ty = try o.lowerType(Type.usize);
9581 function_index.toLlvm(&o.builder).setLinkage(.Internal);
9582 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9583 try o.addCommonFnAttributes(&attributes, function_index.toLlvm(&o.builder));
97419584
9742 const fn_type = try o.builder.fnType(ret_ty, &.{
9743 try o.lowerType(enum_type.tag_ty.toType()),
9744 }, .normal);
9745 const fn_val = o.llvm_module.addFunction(llvm_fn_name.slice(&o.builder).?, fn_type.toLlvm(&o.builder));
9746 fn_val.setLinkage(.Internal);
9747 fn_val.setFunctionCallConv(.Fast);
9748 try o.addCommonFnAttributes(&attributes, fn_val);
9585 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;
9586 function_index.ptr(&o.builder).call_conv = .fastcc;
9587 function_index.ptr(&o.builder).attributes = try attributes.finish(&o.builder);
9588 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
97499589
9750 var global = Builder.Global{
9751 .linkage = .internal,
9752 .type = fn_type,
9753 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9754 };
9755 var function = Builder.Function{
9756 .global = @enumFromInt(o.builder.globals.count()),
9757 .call_conv = .fastcc,
9758 .attributes = try attributes.finish(&o.builder),
9759 };
9760 try o.builder.llvm.globals.append(self.gpa, fn_val);
9761 gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);
9762 try o.builder.functions.append(self.gpa, function);
9763
9764 var wip = try Builder.WipFunction.init(&o.builder, global.kind.function);
9590 var wip = try Builder.WipFunction.init(&o.builder, function_index);
97659591 defer wip.deinit();
97669592 wip.cursor = .{ .block = try wip.block(0, "Entry") };
97679593
......@@ -9817,7 +9643,7 @@ pub const FuncGen = struct {
98179643 _ = try wip.@"unreachable"();
98189644
98199645 try wip.finish();
9820 return global.kind.function;
9646 return function_index;
98219647 }
98229648
98239649 fn getCmpLtErrorsLenFunction(self: *FuncGen) !Builder.Function.Index {
......@@ -9826,33 +9652,23 @@ pub const FuncGen = struct {
98269652 const name = try o.builder.string(lt_errors_fn_name);
98279653 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
98289654
9829 // Function signature: fn (anyerror) bool
9830
9831 const fn_type = try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal);
9832 const llvm_fn = o.llvm_module.addFunction(name.slice(&o.builder).?, fn_type.toLlvm(&o.builder));
9655 const function_index = try o.builder.addFunction(
9656 try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal),
9657 name,
9658 );
98339659
98349660 var attributes: Builder.FunctionAttributes.Wip = .{};
98359661 defer attributes.deinit(&o.builder);
98369662
9837 llvm_fn.setLinkage(.Internal);
9838 llvm_fn.setFunctionCallConv(.Fast);
9839 try o.addCommonFnAttributes(&attributes, llvm_fn);
9663 function_index.toLlvm(&o.builder).setLinkage(.Internal);
9664 function_index.toLlvm(&o.builder).setFunctionCallConv(.Fast);
9665 try o.addCommonFnAttributes(&attributes, function_index.toLlvm(&o.builder));
98409666
9841 var global = Builder.Global{
9842 .linkage = .internal,
9843 .type = fn_type,
9844 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9845 };
9846 var function = Builder.Function{
9847 .global = @enumFromInt(o.builder.globals.count()),
9848 .call_conv = .fastcc,
9849 .attributes = try attributes.finish(&o.builder),
9850 };
9667 function_index.ptrConst(&o.builder).global.ptr(&o.builder).linkage = .internal;
9668 function_index.ptr(&o.builder).call_conv = .fastcc;
9669 function_index.ptr(&o.builder).attributes = try attributes.finish(&o.builder);
98519670
9852 try o.builder.llvm.globals.append(self.gpa, llvm_fn);
9853 _ = try o.builder.addGlobal(name, global);
9854 try o.builder.functions.append(self.gpa, function);
9855 return global.kind.function;
9671 return function_index;
98569672 }
98579673
98589674 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -10416,29 +10232,12 @@ pub const FuncGen = struct {
1041610232 .data => {},
1041710233 }
1041810234
10419 const llvm_fn_name = "llvm.prefetch.p0";
10420 // declare void @llvm.prefetch(i8*, i32, i32, i32)
10421 const llvm_fn_ty = try o.builder.fnType(.void, &.{ .ptr, .i32, .i32, .i32 }, .normal);
10422 const fn_val = o.llvm_module.getNamedFunction(llvm_fn_name) orelse
10423 o.llvm_module.addFunction(llvm_fn_name, llvm_fn_ty.toLlvm(&o.builder));
10424
10425 const ptr = try self.resolveInst(prefetch.ptr);
10426
10427 const params = [_]*llvm.Value{
10428 ptr.toLlvm(&self.wip),
10429 (try o.builder.intConst(.i32, @intFromEnum(prefetch.rw))).toLlvm(&o.builder),
10430 (try o.builder.intConst(.i32, prefetch.locality)).toLlvm(&o.builder),
10431 (try o.builder.intConst(.i32, @intFromEnum(prefetch.cache))).toLlvm(&o.builder),
10432 };
10433 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildCallOld(
10434 llvm_fn_ty.toLlvm(&o.builder),
10435 fn_val,
10436 &params,
10437 params.len,
10438 .C,
10439 .Auto,
10440 "",
10441 ), &self.wip);
10235 _ = try self.wip.callIntrinsic(.prefetch, &.{.ptr}, &.{
10236 try self.resolveInst(prefetch.ptr),
10237 try o.builder.intValue(.i32, prefetch.rw),
10238 try o.builder.intValue(.i32, prefetch.locality),
10239 try o.builder.intValue(.i32, prefetch.cache),
10240 }, "");
1044210241 return .none;
1044310242 }
1044410243
......@@ -10451,26 +10250,20 @@ pub const FuncGen = struct {
1045110250 return self.wip.cast(.addrspacecast, operand, try o.lowerType(inst_ty), "");
1045210251 }
1045310252
10454 fn amdgcnWorkIntrinsic(self: *FuncGen, dimension: u32, default: u32, comptime basename: []const u8) !Builder.Value {
10253 fn amdgcnWorkIntrinsic(
10254 self: *FuncGen,
10255 dimension: u32,
10256 default: u32,
10257 comptime basename: []const u8,
10258 ) !Builder.Value {
1045510259 const o = self.dg.object;
10456 const llvm_fn_name = switch (dimension) {
10457 0 => basename ++ ".x",
10458 1 => basename ++ ".y",
10459 2 => basename ++ ".z",
10260 const intrinsic = switch (dimension) {
10261 0 => @field(Builder.Intrinsic, basename ++ ".x"),
10262 1 => @field(Builder.Intrinsic, basename ++ ".y"),
10263 2 => @field(Builder.Intrinsic, basename ++ ".z"),
1046010264 else => return o.builder.intValue(.i32, default),
1046110265 };
10462
10463 const args: [0]*llvm.Value = .{};
10464 const llvm_fn = try self.getIntrinsic(llvm_fn_name, &.{});
10465 return (try self.wip.unimplemented(.i32, "")).finish(self.builder.buildCallOld(
10466 (try o.builder.fnType(.i32, &.{}, .normal)).toLlvm(&o.builder),
10467 llvm_fn,
10468 &args,
10469 args.len,
10470 .Fast,
10471 .Auto,
10472 "",
10473 ), &self.wip);
10266 return self.wip.callIntrinsic(intrinsic, &.{}, &.{}, "");
1047410267 }
1047510268
1047610269 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -10480,7 +10273,7 @@ pub const FuncGen = struct {
1048010273
1048110274 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1048210275 const dimension = pl_op.payload;
10483 return self.amdgcnWorkIntrinsic(dimension, 0, "llvm.amdgcn.workitem.id");
10276 return self.amdgcnWorkIntrinsic(dimension, 0, "amdgcn.workitem.id");
1048410277 }
1048510278
1048610279 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -10492,27 +10285,9 @@ pub const FuncGen = struct {
1049210285 const dimension = pl_op.payload;
1049310286 if (dimension >= 3) return o.builder.intValue(.i32, 1);
1049410287
10495 var attributes: Builder.FunctionAttributes.Wip = .{};
10496 defer attributes.deinit(&o.builder);
10497
1049810288 // Fetch the dispatch pointer, which points to this structure:
1049910289 // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913
10500 const llvm_fn = try self.getIntrinsic("llvm.amdgcn.dispatch.ptr", &.{});
10501 const args: [0]*llvm.Value = .{};
10502 const llvm_ret_ty = try o.builder.ptrType(Builder.AddrSpace.amdgpu.constant);
10503 const dispatch_ptr = (try self.wip.unimplemented(llvm_ret_ty, "")).finish(self.builder.buildCallOld(
10504 (try o.builder.fnType(llvm_ret_ty, &.{}, .normal)).toLlvm(&o.builder),
10505 llvm_fn,
10506 &args,
10507 args.len,
10508 .Fast,
10509 .Auto,
10510 "",
10511 ), &self.wip);
10512 try attributes.addRetAttr(.{
10513 .@"align" = comptime Builder.Alignment.fromByteUnits(4),
10514 }, &o.builder);
10515 o.addAttrInt(dispatch_ptr.toLlvm(&self.wip), 0, "align", 4);
10290 const dispatch_ptr = try self.wip.callIntrinsic(.@"amdgcn.dispatch.ptr", &.{}, &.{}, "");
1051610291
1051710292 // Load the work_group_* member from the struct as u16.
1051810293 // Just treat the dispatch pointer as an array of u16 to keep things simple.
......@@ -10530,7 +10305,7 @@ pub const FuncGen = struct {
1053010305
1053110306 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1053210307 const dimension = pl_op.payload;
10533 return self.amdgcnWorkIntrinsic(dimension, 0, "llvm.amdgcn.workgroup.id");
10308 return self.amdgcnWorkIntrinsic(dimension, 0, "amdgcn.workgroup.id");
1053410309 }
1053510310
1053610311 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {
......@@ -10716,20 +10491,6 @@ pub const FuncGen = struct {
1071610491 }
1071710492 }
1071810493
10719 fn getIntrinsic(
10720 fg: *FuncGen,
10721 name: []const u8,
10722 types: []const Builder.Type,
10723 ) Allocator.Error!*llvm.Value {
10724 const o = fg.dg.object;
10725 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
10726 assert(id != 0);
10727 const llvm_types = try o.gpa.alloc(*llvm.Type, types.len);
10728 defer o.gpa.free(llvm_types);
10729 for (llvm_types, types) |*llvm_type, ty| llvm_type.* = ty.toLlvm(&o.builder);
10730 return o.llvm_module.getIntrinsicDeclaration(id, llvm_types.ptr, llvm_types.len);
10731 }
10732
1073310494 /// Load a by-ref type by constructing a new alloca and performing a memcpy.
1073410495 fn loadByRef(
1073510496 fg: *FuncGen,
......@@ -10778,7 +10539,7 @@ pub const FuncGen = struct {
1077810539
1077910540 assert(info.flags.vector_index != .runtime);
1078010541 if (info.flags.vector_index != .none) {
10781 const index_u32 = try o.builder.intValue(.i32, @intFromEnum(info.flags.vector_index));
10542 const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index);
1078210543 const vec_elem_ty = try o.lowerType(elem_ty);
1078310544 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
1078410545
......@@ -10848,7 +10609,7 @@ pub const FuncGen = struct {
1084810609
1084910610 assert(info.flags.vector_index != .runtime);
1085010611 if (info.flags.vector_index != .none) {
10851 const index_u32 = try o.builder.intValue(.i32, @intFromEnum(info.flags.vector_index));
10612 const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index);
1085210613 const vec_elem_ty = try o.lowerType(elem_ty);
1085310614 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
1085410615
......@@ -10982,26 +10743,15 @@ pub const FuncGen = struct {
1098210743 else => unreachable,
1098310744 };
1098410745
10985 const fn_llvm_ty = (try o.builder.fnType(llvm_usize, &(.{llvm_usize} ** 2), .normal)).toLlvm(&o.builder);
10986 const array_ptr_as_usize = try fg.wip.cast(.ptrtoint, array_ptr, llvm_usize, "");
10987 const args = [_]*llvm.Value{ array_ptr_as_usize.toLlvm(&fg.wip), default_value.toLlvm(&fg.wip) };
10988 const asm_fn = llvm.getInlineAsm(
10989 fn_llvm_ty,
10990 arch_specific.template.ptr,
10991 arch_specific.template.len,
10992 arch_specific.constraints.ptr,
10993 arch_specific.constraints.len,
10994 .True, // has side effects
10995 .False, // alignstack
10996 .ATT,
10997 .False, // can throw
10998 );
10999
11000 const call = (try fg.wip.unimplemented(llvm_usize, "")).finish(
11001 fg.builder.buildCallOld(fn_llvm_ty, asm_fn, &args, args.len, .C, .Auto, ""),
11002 &fg.wip,
10746 return try fg.wip.callAsm(
10747 .none,
10748 try o.builder.fnType(llvm_usize, &.{ llvm_usize, llvm_usize }, .normal),
10749 .{ .sideeffect = true },
10750 try o.builder.string(arch_specific.template),
10751 try o.builder.string(arch_specific.constraints),
10752 &.{ try fg.wip.cast(.ptrtoint, array_ptr, llvm_usize, ""), default_value },
10753 "",
1100310754 );
11004 return call;
1100510755 }
1100610756
1100710757 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
src/codegen/llvm/Builder.zig+1013-363
......@@ -50,10 +50,12 @@ constant_extra: std.ArrayListUnmanaged(u32),
5050constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb),
5151
5252pub const expected_args_len = 16;
53pub const expected_attrs_len = 16;
5354pub const expected_fields_len = 32;
5455pub const expected_gep_indices_len = 8;
5556pub const expected_cases_len = 8;
5657pub const expected_incoming_len = 8;
58pub const expected_intrinsic_name_len = 64;
5759
5860pub const Options = struct {
5961 allocator: Allocator,
......@@ -151,11 +153,14 @@ pub const Type = enum(u32) {
151153 i80,
152154 i128,
153155 ptr,
156 @"ptr addrspace(4)",
154157
155158 none = std.math.maxInt(u32),
156159 _,
157160
158161 pub const err_int = Type.i16;
162 pub const ptr_amdgpu_constant =
163 @field(Type, std.fmt.comptimePrint("ptr{ }", .{AddrSpace.amdgpu.constant}));
159164
160165 pub const Tag = enum(u4) {
161166 simple,
......@@ -391,7 +396,7 @@ pub const Type = enum(u32) {
391396 .double, .i64, .x86_mmx => 64,
392397 .x86_fp80, .i80 => 80,
393398 .fp128, .ppc_fp128, .i128 => 128,
394 .ptr => @panic("TODO: query data layout"),
399 .ptr, .@"ptr addrspace(4)" => @panic("TODO: query data layout"),
395400 _ => {
396401 const item = builder.type_items.items[@intFromEnum(self)];
397402 return switch (item.tag) {
......@@ -690,7 +695,7 @@ pub const Type = enum(u32) {
690695 }
691696 },
692697 .integer => try writer.print("i{d}", .{item.data}),
693 .pointer => try writer.print("ptr{}", .{@as(AddrSpace, @enumFromInt(item.data))}),
698 .pointer => try writer.print("ptr{ }", .{@as(AddrSpace, @enumFromInt(item.data))}),
694699 .target => {
695700 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
696701 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
......@@ -795,6 +800,7 @@ pub const Type = enum(u32) {
795800 .i80,
796801 .i128,
797802 .ptr,
803 .@"ptr addrspace(4)",
798804 => true,
799805 .none => unreachable,
800806 _ => {
......@@ -1201,12 +1207,20 @@ pub const Attribute = union(Kind) {
12011207 try writer.print(",{d}", .{allocsize.num_elems});
12021208 try writer.writeByte(')');
12031209 },
1204 .memory => |memory| try writer.print(" {s}({s}, argmem: {s}, inaccessiblemem: {s})", .{
1205 @tagName(attribute),
1206 @tagName(memory.other),
1207 @tagName(memory.argmem),
1208 @tagName(memory.inaccessiblemem),
1209 }),
1210 .memory => |memory| {
1211 try writer.print(" {s}(", .{@tagName(attribute)});
1212 var any = memory.other != .none or
1213 (memory.argmem == .none and memory.inaccessiblemem == .none);
1214 if (any) try writer.writeAll(@tagName(memory.other));
1215 inline for (.{ "argmem", "inaccessiblemem" }) |kind| {
1216 if (@field(memory, kind) != memory.other) {
1217 if (any) try writer.writeAll(", ");
1218 try writer.print("{s}: {s}", .{ kind, @tagName(@field(memory, kind)) });
1219 any = true;
1220 }
1221 }
1222 try writer.writeByte(')');
1223 },
12101224 .uwtable => |uwtable| if (uwtable != .none) {
12111225 try writer.print(" {s}", .{@tagName(attribute)});
12121226 if (uwtable != UwTable.default) try writer.print("({s})", .{@tagName(uwtable)});
......@@ -1424,12 +1438,16 @@ pub const Attribute = union(Kind) {
14241438 };
14251439
14261440 pub const Memory = packed struct(u32) {
1427 argmem: Effect,
1428 inaccessiblemem: Effect,
1429 other: Effect,
1441 argmem: Effect = .none,
1442 inaccessiblemem: Effect = .none,
1443 other: Effect = .none,
14301444 _: u26 = 0,
14311445
14321446 pub const Effect = enum(u2) { none, read, write, readwrite };
1447
1448 fn all(effect: Effect) Memory {
1449 return .{ .argmem = effect, .inaccessiblemem = effect, .other = effect };
1450 }
14331451 };
14341452
14351453 pub const UwTable = enum(u32) {
......@@ -2279,6 +2297,820 @@ pub const Variable = struct {
22792297 };
22802298};
22812299
2300pub const Intrinsic = enum {
2301 // Variable Argument Handling
2302 va_start,
2303 va_end,
2304 va_copy,
2305
2306 // Code Generator
2307 returnaddress,
2308 addressofreturnaddress,
2309 sponentry,
2310 frameaddress,
2311 prefetch,
2312 @"thread.pointer",
2313
2314 // Standard C/C++ Library
2315 abs,
2316 smax,
2317 smin,
2318 umax,
2319 umin,
2320 memcpy,
2321 @"memcpy.inline",
2322 memmove,
2323 memset,
2324 @"memset.inline",
2325 sqrt,
2326 powi,
2327 sin,
2328 cos,
2329 pow,
2330 exp,
2331 exp2,
2332 ldexp,
2333 frexp,
2334 log,
2335 log10,
2336 log2,
2337 fma,
2338 fabs,
2339 minnum,
2340 maxnum,
2341 minimum,
2342 maximum,
2343 copysign,
2344 floor,
2345 ceil,
2346 trunc,
2347 rint,
2348 nearbyint,
2349 round,
2350 roundeven,
2351 lround,
2352 llround,
2353 lrint,
2354 llrint,
2355
2356 // Bit Manipulation
2357 bitreverse,
2358 bswap,
2359 ctpop,
2360 ctlz,
2361 cttz,
2362 fshl,
2363 fshr,
2364
2365 // Arithmetic with Overflow
2366 @"sadd.with.overflow",
2367 @"uadd.with.overflow",
2368 @"ssub.with.overflow",
2369 @"usub.with.overflow",
2370 @"smul.with.overflow",
2371 @"umul.with.overflow",
2372
2373 // Saturation Arithmetic
2374 @"sadd.sat",
2375 @"uadd.sat",
2376 @"ssub.sat",
2377 @"usub.sat",
2378 @"sshl.sat",
2379 @"ushl.sat",
2380
2381 // Fixed Point Arithmetic
2382 @"smul.fix",
2383 @"umul.fix",
2384 @"smul.fix.sat",
2385 @"umul.fix.sat",
2386 @"sdiv.fix",
2387 @"udiv.fix",
2388 @"sdiv.fix.sat",
2389 @"udiv.fix.sat",
2390
2391 // Specialised Arithmetic
2392 canonicalisze,
2393 fmuladd,
2394
2395 // Vector Reduction
2396 @"vector.reduce.add",
2397 @"vector.reduce.fadd",
2398 @"vector.reduce.mul",
2399 @"vector.reduce.fmul",
2400 @"vector.reduce.and",
2401 @"vector.reduce.or",
2402 @"vector.reduce.xor",
2403 @"vector.reduce.smax",
2404 @"vector.reduce.smin",
2405 @"vector.reduce.umax",
2406 @"vector.reduce.umin",
2407 @"vector.reduce.fmax",
2408 @"vector.reduce.fmin",
2409 @"vector.reduce.fmaximum",
2410 @"vector.reduce.fminimum",
2411 @"vector.reduce.insert",
2412 @"vector.reduce.extract",
2413 @"vector.insert",
2414 @"vector.extract",
2415
2416 // General
2417 @"llvm.var.annotation",
2418 @"llvm.ptr.annotation",
2419 annotation,
2420 @"codeview.annotation",
2421 trap,
2422 debugtrap,
2423 ubsantrap,
2424 stackprotector,
2425 stackguard,
2426 objectsize,
2427 expect,
2428 @"expect.with.probability",
2429 assume,
2430 @"ssa.copy",
2431 @"type.test",
2432 @"type.checked.load",
2433 @"type.checked.load.relative",
2434 @"arithmetic.fence",
2435 donothing,
2436 @"load.relative",
2437 @"llvm.sideeffect",
2438 @"is.constant",
2439 ptrmask,
2440 @"threadlocal.address",
2441 vscale,
2442
2443 // AMDGPU
2444 @"amdgcn.workitem.id.x",
2445 @"amdgcn.workitem.id.y",
2446 @"amdgcn.workitem.id.z",
2447 @"amdgcn.workgroup.id.x",
2448 @"amdgcn.workgroup.id.y",
2449 @"amdgcn.workgroup.id.z",
2450 @"amdgcn.dispatch.ptr",
2451
2452 // WebAssembly
2453 @"wasm.memory.size",
2454 @"wasm.memory.grow",
2455
2456 const Signature = struct {
2457 params: []const Parameter = &.{},
2458 attrs: []const Attribute = &.{},
2459
2460 const Parameter = struct {
2461 kind: Kind,
2462 attrs: []const Attribute = &.{},
2463
2464 const Kind = union(enum) {
2465 type: Type,
2466 overloaded,
2467 overloaded_tuple: u8,
2468 matches: u8,
2469 matches_tuple: packed struct { param: u4, field: u4 },
2470 matches_with_overflow: u8,
2471 };
2472 };
2473 };
2474
2475 const signatures = std.enums.EnumArray(Intrinsic, Signature).initDefault(.{}, .{
2476 .va_start = .{
2477 .params = &.{
2478 .{ .kind = .{ .type = .void } },
2479 .{ .kind = .{ .type = .ptr } },
2480 },
2481 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn },
2482 },
2483 .va_end = .{
2484 .params = &.{
2485 .{ .kind = .{ .type = .void } },
2486 .{ .kind = .{ .type = .ptr } },
2487 },
2488 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn },
2489 },
2490 .va_copy = .{
2491 .params = &.{
2492 .{ .kind = .{ .type = .void } },
2493 .{ .kind = .{ .type = .ptr } },
2494 .{ .kind = .{ .type = .ptr } },
2495 },
2496 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn },
2497 },
2498
2499 .returnaddress = .{
2500 .params = &.{
2501 .{ .kind = .{ .type = .ptr } },
2502 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2503 },
2504 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2505 },
2506 .addressofreturnaddress = .{
2507 .params = &.{
2508 .{ .kind = .overloaded },
2509 },
2510 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2511 },
2512 .sponentry = .{
2513 .params = &.{
2514 .{ .kind = .overloaded },
2515 },
2516 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2517 },
2518 .frameaddress = .{
2519 .params = &.{
2520 .{ .kind = .overloaded },
2521 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2522 },
2523 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2524 },
2525 .prefetch = .{
2526 .params = &.{
2527 .{ .kind = .{ .type = .void } },
2528 .{ .kind = .overloaded, .attrs = &.{ .nocapture, .readonly } },
2529 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2530 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2531 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2532 },
2533 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.readwrite) } },
2534 },
2535 .@"thread.pointer" = .{
2536 .params = &.{
2537 .{ .kind = .{ .type = .ptr } },
2538 },
2539 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2540 },
2541
2542 .abs = .{
2543 .params = &.{
2544 .{ .kind = .overloaded },
2545 .{ .kind = .{ .matches = 0 } },
2546 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2547 },
2548 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2549 },
2550 .smax = .{
2551 .params = &.{
2552 .{ .kind = .overloaded },
2553 .{ .kind = .{ .matches = 0 } },
2554 .{ .kind = .{ .matches = 0 } },
2555 },
2556 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2557 },
2558 .smin = .{
2559 .params = &.{
2560 .{ .kind = .overloaded },
2561 .{ .kind = .{ .matches = 0 } },
2562 .{ .kind = .{ .matches = 0 } },
2563 },
2564 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2565 },
2566 .umax = .{
2567 .params = &.{
2568 .{ .kind = .overloaded },
2569 .{ .kind = .{ .matches = 0 } },
2570 .{ .kind = .{ .matches = 0 } },
2571 },
2572 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2573 },
2574 .umin = .{
2575 .params = &.{
2576 .{ .kind = .overloaded },
2577 .{ .kind = .{ .matches = 0 } },
2578 .{ .kind = .{ .matches = 0 } },
2579 },
2580 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2581 },
2582 .sqrt = .{
2583 .params = &.{
2584 .{ .kind = .overloaded },
2585 .{ .kind = .{ .matches = 0 } },
2586 },
2587 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2588 },
2589 .powi = .{
2590 .params = &.{
2591 .{ .kind = .overloaded },
2592 .{ .kind = .{ .matches = 0 } },
2593 .{ .kind = .overloaded },
2594 },
2595 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2596 },
2597 .sin = .{
2598 .params = &.{
2599 .{ .kind = .overloaded },
2600 .{ .kind = .{ .matches = 0 } },
2601 },
2602 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2603 },
2604 .cos = .{
2605 .params = &.{
2606 .{ .kind = .overloaded },
2607 .{ .kind = .{ .matches = 0 } },
2608 },
2609 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2610 },
2611 .pow = .{
2612 .params = &.{
2613 .{ .kind = .overloaded },
2614 .{ .kind = .{ .matches = 0 } },
2615 .{ .kind = .{ .matches = 0 } },
2616 },
2617 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2618 },
2619 .exp = .{
2620 .params = &.{
2621 .{ .kind = .overloaded },
2622 .{ .kind = .{ .matches = 0 } },
2623 },
2624 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2625 },
2626 .exp2 = .{
2627 .params = &.{
2628 .{ .kind = .overloaded },
2629 .{ .kind = .{ .matches = 0 } },
2630 },
2631 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2632 },
2633 .ldexp = .{
2634 .params = &.{
2635 .{ .kind = .overloaded },
2636 .{ .kind = .{ .matches = 0 } },
2637 .{ .kind = .overloaded },
2638 },
2639 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2640 },
2641 .frexp = .{
2642 .params = &.{
2643 .{ .kind = .{ .overloaded_tuple = 2 } },
2644 .{ .kind = .{ .matches_tuple = .{ .param = 0, .field = 0 } } },
2645 },
2646 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2647 },
2648 .log = .{
2649 .params = &.{
2650 .{ .kind = .overloaded },
2651 .{ .kind = .{ .matches = 0 } },
2652 },
2653 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2654 },
2655 .log10 = .{
2656 .params = &.{
2657 .{ .kind = .overloaded },
2658 .{ .kind = .{ .matches = 0 } },
2659 },
2660 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2661 },
2662 .log2 = .{
2663 .params = &.{
2664 .{ .kind = .overloaded },
2665 .{ .kind = .{ .matches = 0 } },
2666 },
2667 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2668 },
2669 .fma = .{
2670 .params = &.{
2671 .{ .kind = .overloaded },
2672 .{ .kind = .{ .matches = 0 } },
2673 .{ .kind = .{ .matches = 0 } },
2674 .{ .kind = .{ .matches = 0 } },
2675 },
2676 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2677 },
2678 .fabs = .{
2679 .params = &.{
2680 .{ .kind = .overloaded },
2681 .{ .kind = .{ .matches = 0 } },
2682 },
2683 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2684 },
2685 .minnum = .{
2686 .params = &.{
2687 .{ .kind = .overloaded },
2688 .{ .kind = .{ .matches = 0 } },
2689 .{ .kind = .{ .matches = 0 } },
2690 },
2691 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2692 },
2693 .maxnum = .{
2694 .params = &.{
2695 .{ .kind = .overloaded },
2696 .{ .kind = .{ .matches = 0 } },
2697 .{ .kind = .{ .matches = 0 } },
2698 },
2699 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2700 },
2701 .minimum = .{
2702 .params = &.{
2703 .{ .kind = .overloaded },
2704 .{ .kind = .{ .matches = 0 } },
2705 .{ .kind = .{ .matches = 0 } },
2706 },
2707 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2708 },
2709 .maximum = .{
2710 .params = &.{
2711 .{ .kind = .overloaded },
2712 .{ .kind = .{ .matches = 0 } },
2713 .{ .kind = .{ .matches = 0 } },
2714 },
2715 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2716 },
2717 .copysign = .{
2718 .params = &.{
2719 .{ .kind = .overloaded },
2720 .{ .kind = .{ .matches = 0 } },
2721 .{ .kind = .{ .matches = 0 } },
2722 },
2723 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2724 },
2725 .floor = .{
2726 .params = &.{
2727 .{ .kind = .overloaded },
2728 .{ .kind = .{ .matches = 0 } },
2729 },
2730 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2731 },
2732 .ceil = .{
2733 .params = &.{
2734 .{ .kind = .overloaded },
2735 .{ .kind = .{ .matches = 0 } },
2736 },
2737 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2738 },
2739 .trunc = .{
2740 .params = &.{
2741 .{ .kind = .overloaded },
2742 .{ .kind = .{ .matches = 0 } },
2743 },
2744 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2745 },
2746 .rint = .{
2747 .params = &.{
2748 .{ .kind = .overloaded },
2749 .{ .kind = .{ .matches = 0 } },
2750 },
2751 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2752 },
2753 .nearbyint = .{
2754 .params = &.{
2755 .{ .kind = .overloaded },
2756 .{ .kind = .{ .matches = 0 } },
2757 },
2758 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2759 },
2760 .round = .{
2761 .params = &.{
2762 .{ .kind = .overloaded },
2763 .{ .kind = .{ .matches = 0 } },
2764 },
2765 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2766 },
2767 .roundeven = .{
2768 .params = &.{
2769 .{ .kind = .overloaded },
2770 .{ .kind = .{ .matches = 0 } },
2771 },
2772 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2773 },
2774 .lround = .{
2775 .params = &.{
2776 .{ .kind = .overloaded },
2777 .{ .kind = .overloaded },
2778 },
2779 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2780 },
2781 .llround = .{
2782 .params = &.{
2783 .{ .kind = .overloaded },
2784 .{ .kind = .overloaded },
2785 },
2786 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2787 },
2788 .lrint = .{
2789 .params = &.{
2790 .{ .kind = .overloaded },
2791 .{ .kind = .overloaded },
2792 },
2793 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2794 },
2795 .llrint = .{
2796 .params = &.{
2797 .{ .kind = .overloaded },
2798 .{ .kind = .overloaded },
2799 },
2800 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2801 },
2802
2803 .bitreverse = .{
2804 .params = &.{
2805 .{ .kind = .overloaded },
2806 .{ .kind = .{ .matches = 0 } },
2807 },
2808 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2809 },
2810 .bswap = .{
2811 .params = &.{
2812 .{ .kind = .overloaded },
2813 .{ .kind = .{ .matches = 0 } },
2814 },
2815 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2816 },
2817 .ctpop = .{
2818 .params = &.{
2819 .{ .kind = .overloaded },
2820 .{ .kind = .{ .matches = 0 } },
2821 },
2822 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2823 },
2824 .ctlz = .{
2825 .params = &.{
2826 .{ .kind = .overloaded },
2827 .{ .kind = .{ .matches = 0 } },
2828 .{ .kind = .{ .type = .i1 } },
2829 },
2830 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2831 },
2832 .cttz = .{
2833 .params = &.{
2834 .{ .kind = .overloaded },
2835 .{ .kind = .{ .matches = 0 } },
2836 .{ .kind = .{ .type = .i1 } },
2837 },
2838 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2839 },
2840 .fshl = .{
2841 .params = &.{
2842 .{ .kind = .overloaded },
2843 .{ .kind = .{ .matches = 0 } },
2844 .{ .kind = .{ .matches = 0 } },
2845 .{ .kind = .{ .matches = 0 } },
2846 },
2847 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2848 },
2849 .fshr = .{
2850 .params = &.{
2851 .{ .kind = .overloaded },
2852 .{ .kind = .{ .matches = 0 } },
2853 .{ .kind = .{ .matches = 0 } },
2854 .{ .kind = .{ .matches = 0 } },
2855 },
2856 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2857 },
2858
2859 .@"sadd.with.overflow" = .{
2860 .params = &.{
2861 .{ .kind = .{ .matches_with_overflow = 1 } },
2862 .{ .kind = .overloaded },
2863 .{ .kind = .{ .matches = 1 } },
2864 },
2865 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2866 },
2867 .@"uadd.with.overflow" = .{
2868 .params = &.{
2869 .{ .kind = .{ .matches_with_overflow = 1 } },
2870 .{ .kind = .overloaded },
2871 .{ .kind = .{ .matches = 1 } },
2872 },
2873 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2874 },
2875 .@"ssub.with.overflow" = .{
2876 .params = &.{
2877 .{ .kind = .{ .matches_with_overflow = 1 } },
2878 .{ .kind = .overloaded },
2879 .{ .kind = .{ .matches = 1 } },
2880 },
2881 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2882 },
2883 .@"usub.with.overflow" = .{
2884 .params = &.{
2885 .{ .kind = .{ .matches_with_overflow = 1 } },
2886 .{ .kind = .overloaded },
2887 .{ .kind = .{ .matches = 1 } },
2888 },
2889 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2890 },
2891 .@"smul.with.overflow" = .{
2892 .params = &.{
2893 .{ .kind = .{ .matches_with_overflow = 1 } },
2894 .{ .kind = .overloaded },
2895 .{ .kind = .{ .matches = 1 } },
2896 },
2897 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2898 },
2899 .@"umul.with.overflow" = .{
2900 .params = &.{
2901 .{ .kind = .{ .matches_with_overflow = 1 } },
2902 .{ .kind = .overloaded },
2903 .{ .kind = .{ .matches = 1 } },
2904 },
2905 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2906 },
2907
2908 .@"sadd.sat" = .{
2909 .params = &.{
2910 .{ .kind = .overloaded },
2911 .{ .kind = .{ .matches = 0 } },
2912 .{ .kind = .{ .matches = 0 } },
2913 },
2914 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2915 },
2916 .@"uadd.sat" = .{
2917 .params = &.{
2918 .{ .kind = .overloaded },
2919 .{ .kind = .{ .matches = 0 } },
2920 .{ .kind = .{ .matches = 0 } },
2921 },
2922 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2923 },
2924 .@"ssub.sat" = .{
2925 .params = &.{
2926 .{ .kind = .overloaded },
2927 .{ .kind = .{ .matches = 0 } },
2928 .{ .kind = .{ .matches = 0 } },
2929 },
2930 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2931 },
2932 .@"usub.sat" = .{
2933 .params = &.{
2934 .{ .kind = .overloaded },
2935 .{ .kind = .{ .matches = 0 } },
2936 .{ .kind = .{ .matches = 0 } },
2937 },
2938 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2939 },
2940 .@"sshl.sat" = .{
2941 .params = &.{
2942 .{ .kind = .overloaded },
2943 .{ .kind = .{ .matches = 0 } },
2944 .{ .kind = .{ .matches = 0 } },
2945 },
2946 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2947 },
2948 .@"ushl.sat" = .{
2949 .params = &.{
2950 .{ .kind = .overloaded },
2951 .{ .kind = .{ .matches = 0 } },
2952 .{ .kind = .{ .matches = 0 } },
2953 },
2954 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2955 },
2956
2957 .@"smul.fix" = .{
2958 .params = &.{
2959 .{ .kind = .overloaded },
2960 .{ .kind = .{ .matches = 0 } },
2961 .{ .kind = .{ .matches = 0 } },
2962 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2963 },
2964 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2965 },
2966 .@"umul.fix" = .{
2967 .params = &.{
2968 .{ .kind = .overloaded },
2969 .{ .kind = .{ .matches = 0 } },
2970 .{ .kind = .{ .matches = 0 } },
2971 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2972 },
2973 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2974 },
2975 .@"smul.fix.sat" = .{
2976 .params = &.{
2977 .{ .kind = .overloaded },
2978 .{ .kind = .{ .matches = 0 } },
2979 .{ .kind = .{ .matches = 0 } },
2980 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2981 },
2982 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2983 },
2984 .@"umul.fix.sat" = .{
2985 .params = &.{
2986 .{ .kind = .overloaded },
2987 .{ .kind = .{ .matches = 0 } },
2988 .{ .kind = .{ .matches = 0 } },
2989 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2990 },
2991 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2992 },
2993 .@"sdiv.fix" = .{
2994 .params = &.{
2995 .{ .kind = .overloaded },
2996 .{ .kind = .{ .matches = 0 } },
2997 .{ .kind = .{ .matches = 0 } },
2998 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
2999 },
3000 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3001 },
3002 .@"udiv.fix" = .{
3003 .params = &.{
3004 .{ .kind = .overloaded },
3005 .{ .kind = .{ .matches = 0 } },
3006 .{ .kind = .{ .matches = 0 } },
3007 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3008 },
3009 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3010 },
3011 .@"sdiv.fix.sat" = .{
3012 .params = &.{
3013 .{ .kind = .overloaded },
3014 .{ .kind = .{ .matches = 0 } },
3015 .{ .kind = .{ .matches = 0 } },
3016 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3017 },
3018 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3019 },
3020 .@"udiv.fix.sat" = .{
3021 .params = &.{
3022 .{ .kind = .overloaded },
3023 .{ .kind = .{ .matches = 0 } },
3024 .{ .kind = .{ .matches = 0 } },
3025 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3026 },
3027 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3028 },
3029
3030 .trap = .{
3031 .params = &.{
3032 .{ .kind = .{ .type = .void } },
3033 },
3034 .attrs = &.{ .cold, .noreturn, .nounwind, .{ .memory = .{ .inaccessiblemem = .write } } },
3035 },
3036 .debugtrap = .{
3037 .params = &.{
3038 .{ .kind = .{ .type = .void } },
3039 },
3040 .attrs = &.{.nounwind},
3041 },
3042 .ubsantrap = .{
3043 .params = &.{
3044 .{ .kind = .{ .type = .void } },
3045 .{ .kind = .{ .type = .i8 }, .attrs = &.{.immarg} },
3046 },
3047 .attrs = &.{ .cold, .noreturn, .nounwind },
3048 },
3049
3050 .@"amdgcn.workitem.id.x" = .{
3051 .params = &.{
3052 .{ .kind = .{ .type = .i32 } },
3053 },
3054 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3055 },
3056 .@"amdgcn.workitem.id.y" = .{
3057 .params = &.{
3058 .{ .kind = .{ .type = .i32 } },
3059 },
3060 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3061 },
3062 .@"amdgcn.workitem.id.z" = .{
3063 .params = &.{
3064 .{ .kind = .{ .type = .i32 } },
3065 },
3066 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3067 },
3068 .@"amdgcn.workgroup.id.x" = .{
3069 .params = &.{
3070 .{ .kind = .{ .type = .i32 } },
3071 },
3072 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3073 },
3074 .@"amdgcn.workgroup.id.y" = .{
3075 .params = &.{
3076 .{ .kind = .{ .type = .i32 } },
3077 },
3078 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3079 },
3080 .@"amdgcn.workgroup.id.z" = .{
3081 .params = &.{
3082 .{ .kind = .{ .type = .i32 } },
3083 },
3084 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3085 },
3086 .@"amdgcn.dispatch.ptr" = .{
3087 .params = &.{
3088 .{
3089 .kind = .{ .type = Type.ptr_amdgpu_constant },
3090 .attrs = &.{.{ .@"align" = Builder.Alignment.fromByteUnits(4) }},
3091 },
3092 },
3093 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3094 },
3095
3096 .@"wasm.memory.size" = .{
3097 .params = &.{
3098 .{ .kind = .overloaded },
3099 .{ .kind = .{ .type = .i32 } },
3100 },
3101 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3102 },
3103 .@"wasm.memory.grow" = .{
3104 .params = &.{
3105 .{ .kind = .overloaded },
3106 .{ .kind = .{ .type = .i32 } },
3107 .{ .kind = .{ .matches = 0 } },
3108 },
3109 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn },
3110 },
3111 });
3112};
3113
22823114pub const Function = struct {
22833115 global: Global.Index,
22843116 call_conv: CallConv = CallConv.default,
......@@ -2414,39 +3246,6 @@ pub const Function = struct {
24143246 insertelement,
24153247 insertvalue,
24163248 inttoptr,
2417 @"llvm.maxnum.",
2418 @"llvm.minnum.",
2419 @"llvm.ceil.",
2420 @"llvm.cos.",
2421 @"llvm.exp.",
2422 @"llvm.exp2.",
2423 @"llvm.fabs.",
2424 @"llvm.floor.",
2425 @"llvm.log.",
2426 @"llvm.log10.",
2427 @"llvm.log2.",
2428 @"llvm.round.",
2429 @"llvm.sin.",
2430 @"llvm.sqrt.",
2431 @"llvm.trunc.",
2432 @"llvm.fma.",
2433 @"llvm.bitreverse.",
2434 @"llvm.bswap.",
2435 @"llvm.ctpop.",
2436 @"llvm.ctlz.",
2437 @"llvm.cttz.",
2438 @"llvm.sadd.sat.",
2439 @"llvm.smax.",
2440 @"llvm.smin.",
2441 @"llvm.smul.fix.sat.",
2442 @"llvm.sshl.sat.",
2443 @"llvm.ssub.sat.",
2444 @"llvm.uadd.sat.",
2445 @"llvm.umax.",
2446 @"llvm.umin.",
2447 @"llvm.umul.fix.sat.",
2448 @"llvm.ushl.sat.",
2449 @"llvm.usub.sat.",
24503249 load,
24513250 @"load atomic",
24523251 @"load atomic volatile",
......@@ -2575,22 +3374,6 @@ pub const Function = struct {
25753374 .@"frem fast",
25763375 .fsub,
25773376 .@"fsub fast",
2578 .@"llvm.maxnum.",
2579 .@"llvm.minnum.",
2580 .@"llvm.ctlz.",
2581 .@"llvm.cttz.",
2582 .@"llvm.sadd.sat.",
2583 .@"llvm.smax.",
2584 .@"llvm.smin.",
2585 .@"llvm.smul.fix.sat.",
2586 .@"llvm.sshl.sat.",
2587 .@"llvm.ssub.sat.",
2588 .@"llvm.uadd.sat.",
2589 .@"llvm.umax.",
2590 .@"llvm.umin.",
2591 .@"llvm.umul.fix.sat.",
2592 .@"llvm.ushl.sat.",
2593 .@"llvm.usub.sat.",
25943377 .lshr,
25953378 .@"lshr exact",
25963379 .mul,
......@@ -2710,22 +3493,6 @@ pub const Function = struct {
27103493 .changeScalarAssumeCapacity(.i1, wip.builder),
27113494 .fneg,
27123495 .@"fneg fast",
2713 .@"llvm.ceil.",
2714 .@"llvm.cos.",
2715 .@"llvm.exp.",
2716 .@"llvm.exp2.",
2717 .@"llvm.fabs.",
2718 .@"llvm.floor.",
2719 .@"llvm.log.",
2720 .@"llvm.log10.",
2721 .@"llvm.log2.",
2722 .@"llvm.round.",
2723 .@"llvm.sin.",
2724 .@"llvm.sqrt.",
2725 .@"llvm.trunc.",
2726 .@"llvm.bitreverse.",
2727 .@"llvm.bswap.",
2728 .@"llvm.ctpop.",
27293496 => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip),
27303497 .getelementptr,
27313498 .@"getelementptr inbounds",
......@@ -2762,7 +3529,6 @@ pub const Function = struct {
27623529 },
27633530 .unimplemented => @enumFromInt(instruction.data),
27643531 .va_arg => wip.extraData(VaArg, instruction.data).type,
2765 .@"llvm.fma." => wip.extraData(FusedMultiplyAdd, instruction.data).a.typeOfWip(wip),
27663532 };
27673533 }
27683534
......@@ -2791,22 +3557,6 @@ pub const Function = struct {
27913557 .@"frem fast",
27923558 .fsub,
27933559 .@"fsub fast",
2794 .@"llvm.maxnum.",
2795 .@"llvm.minnum.",
2796 .@"llvm.ctlz.",
2797 .@"llvm.cttz.",
2798 .@"llvm.sadd.sat.",
2799 .@"llvm.smax.",
2800 .@"llvm.smin.",
2801 .@"llvm.smul.fix.sat.",
2802 .@"llvm.sshl.sat.",
2803 .@"llvm.ssub.sat.",
2804 .@"llvm.uadd.sat.",
2805 .@"llvm.umax.",
2806 .@"llvm.umin.",
2807 .@"llvm.umul.fix.sat.",
2808 .@"llvm.ushl.sat.",
2809 .@"llvm.usub.sat.",
28103560 .lshr,
28113561 .@"lshr exact",
28123562 .mul,
......@@ -2927,22 +3677,6 @@ pub const Function = struct {
29273677 .changeScalarAssumeCapacity(.i1, builder),
29283678 .fneg,
29293679 .@"fneg fast",
2930 .@"llvm.ceil.",
2931 .@"llvm.cos.",
2932 .@"llvm.exp.",
2933 .@"llvm.exp2.",
2934 .@"llvm.fabs.",
2935 .@"llvm.floor.",
2936 .@"llvm.log.",
2937 .@"llvm.log10.",
2938 .@"llvm.log2.",
2939 .@"llvm.round.",
2940 .@"llvm.sin.",
2941 .@"llvm.sqrt.",
2942 .@"llvm.trunc.",
2943 .@"llvm.bitreverse.",
2944 .@"llvm.bswap.",
2945 .@"llvm.ctpop.",
29463680 => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder),
29473681 .getelementptr,
29483682 .@"getelementptr inbounds",
......@@ -2981,7 +3715,6 @@ pub const Function = struct {
29813715 },
29823716 .unimplemented => @enumFromInt(instruction.data),
29833717 .va_arg => function.extraData(VaArg, instruction.data).type,
2984 .@"llvm.fma." => function.extraData(FusedMultiplyAdd, instruction.data).a.typeOf(function_index, builder),
29853718 };
29863719 }
29873720
......@@ -3074,12 +3807,6 @@ pub const Function = struct {
30743807 mask: Value,
30753808 };
30763809
3077 pub const FusedMultiplyAdd = struct {
3078 a: Value,
3079 b: Value,
3080 c: Value,
3081 };
3082
30833810 pub const ExtractValue = struct {
30843811 val: Value,
30853812 indices_len: u32,
......@@ -3487,24 +4214,7 @@ pub const WipFunction = struct {
34874214 switch (tag) {
34884215 .fneg,
34894216 .@"fneg fast",
3490 .@"llvm.ceil.",
3491 .@"llvm.cos.",
3492 .@"llvm.exp.",
3493 .@"llvm.exp2.",
3494 .@"llvm.fabs.",
3495 .@"llvm.floor.",
3496 .@"llvm.log.",
3497 .@"llvm.log10.",
3498 .@"llvm.log2.",
3499 .@"llvm.round.",
3500 .@"llvm.sin.",
3501 .@"llvm.sqrt.",
3502 .@"llvm.trunc.",
35034217 => assert(val.typeOfWip(self).scalarType(self.builder).isFloatingPoint()),
3504 .@"llvm.bitreverse.",
3505 .@"llvm.bswap.",
3506 .@"llvm.ctpop.",
3507 => assert(val.typeOfWip(self).scalarType(self.builder).isInteger(self.builder)),
35084218 else => unreachable,
35094219 }
35104220 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
......@@ -3513,43 +4223,10 @@ pub const WipFunction = struct {
35134223 switch (tag) {
35144224 .fneg => self.llvm.builder.setFastMath(false),
35154225 .@"fneg fast" => self.llvm.builder.setFastMath(true),
3516 .@"llvm.ceil.",
3517 .@"llvm.cos.",
3518 .@"llvm.exp.",
3519 .@"llvm.exp2.",
3520 .@"llvm.fabs.",
3521 .@"llvm.floor.",
3522 .@"llvm.log.",
3523 .@"llvm.log10.",
3524 .@"llvm.log2.",
3525 .@"llvm.round.",
3526 .@"llvm.sin.",
3527 .@"llvm.sqrt.",
3528 .@"llvm.trunc.",
3529 .@"llvm.bitreverse.",
3530 .@"llvm.bswap.",
3531 .@"llvm.ctpop.",
3532 => {},
35334226 else => unreachable,
35344227 }
35354228 self.llvm.instructions.appendAssumeCapacity(switch (tag) {
35364229 .fneg, .@"fneg fast" => &llvm.Builder.buildFNeg,
3537 .@"llvm.ceil." => &llvm.Builder.buildCeil,
3538 .@"llvm.cos." => &llvm.Builder.buildCos,
3539 .@"llvm.exp." => &llvm.Builder.buildExp,
3540 .@"llvm.exp2." => &llvm.Builder.buildExp2,
3541 .@"llvm.fabs." => &llvm.Builder.buildFAbs,
3542 .@"llvm.floor." => &llvm.Builder.buildFloor,
3543 .@"llvm.log." => &llvm.Builder.buildLog,
3544 .@"llvm.log10." => &llvm.Builder.buildLog10,
3545 .@"llvm.log2." => &llvm.Builder.buildLog2,
3546 .@"llvm.round." => &llvm.Builder.buildRound,
3547 .@"llvm.sin." => &llvm.Builder.buildSin,
3548 .@"llvm.sqrt." => &llvm.Builder.buildSqrt,
3549 .@"llvm.trunc." => &llvm.Builder.buildFTrunc,
3550 .@"llvm.bitreverse." => &llvm.Builder.buildBitReverse,
3551 .@"llvm.bswap." => &llvm.Builder.buildBSwap,
3552 .@"llvm.ctpop." => &llvm.Builder.buildCTPop,
35534230 else => unreachable,
35544231 }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self)));
35554232 }
......@@ -3593,20 +4270,6 @@ pub const WipFunction = struct {
35934270 .@"frem fast",
35944271 .fsub,
35954272 .@"fsub fast",
3596 .@"llvm.maxnum.",
3597 .@"llvm.minnum.",
3598 .@"llvm.sadd.sat.",
3599 .@"llvm.smax.",
3600 .@"llvm.smin.",
3601 .@"llvm.smul.fix.sat.",
3602 .@"llvm.sshl.sat.",
3603 .@"llvm.ssub.sat.",
3604 .@"llvm.uadd.sat.",
3605 .@"llvm.umax.",
3606 .@"llvm.umin.",
3607 .@"llvm.umul.fix.sat.",
3608 .@"llvm.ushl.sat.",
3609 .@"llvm.usub.sat.",
36104273 .lshr,
36114274 .@"lshr exact",
36124275 .mul,
......@@ -3627,9 +4290,6 @@ pub const WipFunction = struct {
36274290 .urem,
36284291 .xor,
36294292 => assert(lhs.typeOfWip(self) == rhs.typeOfWip(self)),
3630 .@"llvm.ctlz.",
3631 .@"llvm.cttz.",
3632 => assert(lhs.typeOfWip(self).scalarType(self.builder).isInteger(self.builder) and rhs.typeOfWip(self) == .i1),
36334293 else => unreachable,
36344294 }
36354295 try self.ensureUnusedExtraCapacity(1, Instruction.Binary, 0);
......@@ -3665,22 +4325,6 @@ pub const WipFunction = struct {
36654325 .fmul, .@"fmul fast" => &llvm.Builder.buildFMul,
36664326 .frem, .@"frem fast" => &llvm.Builder.buildFRem,
36674327 .fsub, .@"fsub fast" => &llvm.Builder.buildFSub,
3668 .@"llvm.maxnum." => &llvm.Builder.buildMaxNum,
3669 .@"llvm.minnum." => &llvm.Builder.buildMinNum,
3670 .@"llvm.ctlz." => &llvm.Builder.buildCTLZ,
3671 .@"llvm.cttz." => &llvm.Builder.buildCTTZ,
3672 .@"llvm.sadd.sat." => &llvm.Builder.buildSAddSat,
3673 .@"llvm.smax." => &llvm.Builder.buildSMax,
3674 .@"llvm.smin." => &llvm.Builder.buildSMin,
3675 .@"llvm.smul.fix.sat." => &llvm.Builder.buildSMulFixSat,
3676 .@"llvm.sshl.sat." => &llvm.Builder.buildSShlSat,
3677 .@"llvm.ssub.sat." => &llvm.Builder.buildSSubSat,
3678 .@"llvm.uadd.sat." => &llvm.Builder.buildUAddSat,
3679 .@"llvm.umax." => &llvm.Builder.buildUMax,
3680 .@"llvm.umin." => &llvm.Builder.buildUMin,
3681 .@"llvm.umul.fix.sat." => &llvm.Builder.buildUMulFixSat,
3682 .@"llvm.ushl.sat." => &llvm.Builder.buildUShlSat,
3683 .@"llvm.usub.sat." => &llvm.Builder.buildUSubSat,
36844328 .lshr => &llvm.Builder.buildLShr,
36854329 .@"lshr exact" => &llvm.Builder.buildLShrExact,
36864330 .mul => &llvm.Builder.buildMul,
......@@ -4419,7 +5063,7 @@ pub const WipFunction = struct {
44195063 self: *WipFunction,
44205064 function_attributes: FunctionAttributes,
44215065 ty: Type,
4422 kind: Constant.Asm.Info,
5066 kind: Constant.Assembly.Info,
44235067 assembly: String,
44245068 constraints: String,
44255069 args: []const Value,
......@@ -4429,6 +5073,25 @@ pub const WipFunction = struct {
44295073 return self.call(.normal, CallConv.default, function_attributes, ty, callee, args, name);
44305074 }
44315075
5076 pub fn callIntrinsic(
5077 self: *WipFunction,
5078 id: Intrinsic,
5079 overload: []const Type,
5080 args: []const Value,
5081 name: []const u8,
5082 ) Allocator.Error!Value {
5083 const intrinsic = try self.builder.getIntrinsic(id, overload);
5084 return self.call(
5085 .normal,
5086 CallConv.default,
5087 .none,
5088 intrinsic.typeOf(self.builder),
5089 intrinsic.toValue(self.builder),
5090 args,
5091 name,
5092 );
5093 }
5094
44325095 pub fn vaArg(self: *WipFunction, list: Value, ty: Type, name: []const u8) Allocator.Error!Value {
44335096 try self.ensureUnusedExtraCapacity(1, Instruction.VaArg, 0);
44345097 const instruction = try self.addInst(name, .{
......@@ -4448,29 +5111,6 @@ pub const WipFunction = struct {
44485111 return instruction.toValue();
44495112 }
44505113
4451 pub fn fusedMultiplyAdd(self: *WipFunction, a: Value, b: Value, c: Value) Allocator.Error!Value {
4452 assert(a.typeOfWip(self) == b.typeOfWip(self) and a.typeOfWip(self) == c.typeOfWip(self));
4453 try self.ensureUnusedExtraCapacity(1, Instruction.FusedMultiplyAdd, 0);
4454 const instruction = try self.addInst("", .{
4455 .tag = .@"llvm.fma.",
4456 .data = self.addExtraAssumeCapacity(Instruction.FusedMultiplyAdd{
4457 .a = a,
4458 .b = b,
4459 .c = c,
4460 }),
4461 });
4462 if (self.builder.useLibLlvm()) {
4463 self.llvm.instructions.appendAssumeCapacity(llvm.Builder.buildFMA(
4464 self.llvm.builder,
4465 a.toLlvm(self),
4466 b.toLlvm(self),
4467 c.toLlvm(self),
4468 instruction.llvmName(self),
4469 ));
4470 }
4471 return instruction.toValue();
4472 }
4473
44745114 pub const WipUnimplemented = struct {
44755115 instruction: Instruction.Index,
44765116
......@@ -4697,22 +5337,6 @@ pub const WipFunction = struct {
46975337 .@"icmp ugt",
46985338 .@"icmp ule",
46995339 .@"icmp ult",
4700 .@"llvm.maxnum.",
4701 .@"llvm.minnum.",
4702 .@"llvm.ctlz.",
4703 .@"llvm.cttz.",
4704 .@"llvm.sadd.sat.",
4705 .@"llvm.smax.",
4706 .@"llvm.smin.",
4707 .@"llvm.smul.fix.sat.",
4708 .@"llvm.sshl.sat.",
4709 .@"llvm.ssub.sat.",
4710 .@"llvm.uadd.sat.",
4711 .@"llvm.umax.",
4712 .@"llvm.umin.",
4713 .@"llvm.umul.fix.sat.",
4714 .@"llvm.ushl.sat.",
4715 .@"llvm.usub.sat.",
47165340 .lshr,
47175341 .@"lshr exact",
47185342 .mul,
......@@ -4828,22 +5452,6 @@ pub const WipFunction = struct {
48285452 .fneg,
48295453 .@"fneg fast",
48305454 .ret,
4831 .@"llvm.ceil.",
4832 .@"llvm.cos.",
4833 .@"llvm.exp.",
4834 .@"llvm.exp2.",
4835 .@"llvm.fabs.",
4836 .@"llvm.floor.",
4837 .@"llvm.log.",
4838 .@"llvm.log10.",
4839 .@"llvm.log2.",
4840 .@"llvm.round.",
4841 .@"llvm.sin.",
4842 .@"llvm.sqrt.",
4843 .@"llvm.trunc.",
4844 .@"llvm.bitreverse.",
4845 .@"llvm.bswap.",
4846 .@"llvm.ctpop.",
48475455 => instruction.data = @intFromEnum(instructions.map(@enumFromInt(instruction.data))),
48485456 .getelementptr,
48495457 .@"getelementptr inbounds",
......@@ -4949,14 +5557,6 @@ pub const WipFunction = struct {
49495557 .type = extra.type,
49505558 });
49515559 },
4952 .@"llvm.fma." => {
4953 const extra = self.extraData(Instruction.FusedMultiplyAdd, instruction.data);
4954 instruction.data = wip_extra.addExtra(Instruction.FusedMultiplyAdd{
4955 .a = instructions.map(extra.a),
4956 .b = instructions.map(extra.b),
4957 .c = instructions.map(extra.c),
4958 });
4959 },
49605560 }
49615561 function.instructions.appendAssumeCapacity(instruction);
49625562 names[@intFromEnum(new_instruction_index)] = wip_name.map(if (self.builder.strip)
......@@ -5627,7 +6227,7 @@ pub const Constant = enum(u32) {
56276227 rhs: Constant,
56286228 };
56296229
5630 pub const Asm = extern struct {
6230 pub const Assembly = extern struct {
56316231 type: Type,
56326232 assembly: String,
56336233 constraints: String,
......@@ -5651,7 +6251,7 @@ pub const Constant = enum(u32) {
56516251 }
56526252
56536253 pub fn toValue(self: Constant) Value {
5654 return @enumFromInt(@intFromEnum(Value.first_constant) + @intFromEnum(self));
6254 return @enumFromInt(Value.first_constant + @intFromEnum(self));
56556255 }
56566256
56576257 pub fn typeOf(self: Constant, builder: *Builder) Type {
......@@ -6139,7 +6739,7 @@ pub const Constant = enum(u32) {
61396739 .@"asm alignstack inteldialect unwind",
61406740 .@"asm sideeffect alignstack inteldialect unwind",
61416741 => |tag| {
6142 const extra = data.builder.constantExtraData(Asm, item.data);
6742 const extra = data.builder.constantExtraData(Assembly, item.data);
61436743 try writer.print("{s} {\"}, {\"}", .{
61446744 @tagName(tag),
61456745 extra.assembly.fmt(data.builder),
......@@ -6166,18 +6766,20 @@ pub const Constant = enum(u32) {
61666766
61676767pub const Value = enum(u32) {
61686768 none = std.math.maxInt(u31),
6769 false = first_constant + @intFromEnum(Constant.false),
6770 true = first_constant + @intFromEnum(Constant.true),
61696771 _,
61706772
6171 const first_constant: Value = @enumFromInt(1 << 31);
6773 const first_constant = 1 << 31;
61726774
61736775 pub fn unwrap(self: Value) union(enum) {
61746776 instruction: Function.Instruction.Index,
61756777 constant: Constant,
61766778 } {
6177 return if (@intFromEnum(self) < @intFromEnum(first_constant))
6779 return if (@intFromEnum(self) < first_constant)
61786780 .{ .instruction = @enumFromInt(@intFromEnum(self)) }
61796781 else
6180 .{ .constant = @enumFromInt(@intFromEnum(self) - @intFromEnum(first_constant)) };
6782 .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) };
61816783 }
61826784
61836785 pub fn typeOfWip(self: Value, wip: *const WipFunction) Type {
......@@ -6349,8 +6951,11 @@ pub fn init(options: Options) InitError!Builder {
63496951 inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits|
63506952 assert(self.intTypeAssumeCapacity(bits) ==
63516953 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
6352 inline for (.{0}) |addr_space|
6353 assert(self.ptrTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);
6954 inline for (.{ 0, 4 }) |addr_space_index| {
6955 const addr_space: AddrSpace = @enumFromInt(addr_space_index);
6956 assert(self.ptrTypeAssumeCapacity(addr_space) ==
6957 @field(Type, std.fmt.comptimePrint("ptr{ }", .{addr_space})));
6958 }
63546959 }
63556960
63566961 {
......@@ -6883,17 +7488,136 @@ pub fn getGlobal(self: *const Builder, name: String) ?Global.Index {
68837488 return @enumFromInt(self.globals.getIndex(name) orelse return null);
68847489}
68857490
7491pub fn addFunction(self: *Builder, ty: Type, name: String) Allocator.Error!Function.Index {
7492 assert(!name.isAnon());
7493 try self.ensureUnusedTypeCapacity(1, NoExtra, 0);
7494 try self.ensureUnusedGlobalCapacity(name);
7495 try self.functions.ensureUnusedCapacity(self.gpa, 1);
7496 return self.addFunctionAssumeCapacity(ty, name);
7497}
7498
7499pub fn addFunctionAssumeCapacity(self: *Builder, ty: Type, name: String) Function.Index {
7500 assert(ty.isFunction(self));
7501 if (self.useLibLlvm()) self.llvm.globals.appendAssumeCapacity(
7502 self.llvm.module.?.addFunction(name.slice(self).?, ty.toLlvm(self)),
7503 );
7504 const function_index: Function.Index = @enumFromInt(self.functions.items.len);
7505 self.functions.appendAssumeCapacity(.{ .global = self.addGlobalAssumeCapacity(name, .{
7506 .type = ty,
7507 .kind = .{ .function = function_index },
7508 }) });
7509 return function_index;
7510}
7511
7512pub fn getIntrinsic(
7513 self: *Builder,
7514 id: Intrinsic,
7515 overload: []const Type,
7516) Allocator.Error!Function.Index {
7517 const ExpectedContents = extern union {
7518 name: [expected_intrinsic_name_len]u8,
7519 attrs: extern struct {
7520 params: [expected_args_len]Type,
7521 fn_attrs: [FunctionAttributes.params_index + expected_args_len]Attributes,
7522 attrs: [expected_attrs_len]Attribute.Index,
7523 fields: [expected_fields_len]Type,
7524 },
7525 };
7526 var stack align(@max(@alignOf(std.heap.StackFallbackAllocator(0)), @alignOf(ExpectedContents))) =
7527 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
7528 const allocator = stack.get();
7529
7530 const name = name: {
7531 var buffer = std.ArrayList(u8).init(allocator);
7532 defer buffer.deinit();
7533
7534 try buffer.writer().print("llvm.{s}", .{@tagName(id)});
7535 for (overload) |ty| try buffer.writer().print(".{m}", .{ty.fmt(self)});
7536 break :name try self.string(buffer.items);
7537 };
7538 if (self.getGlobal(name)) |global| return global.ptrConst(self).kind.function;
7539
7540 const signature = Intrinsic.signatures.get(id);
7541 const param_types = try allocator.alloc(Type, signature.params.len);
7542 defer allocator.free(param_types);
7543 const function_attributes =
7544 try allocator.alloc(Attributes, FunctionAttributes.return_index + signature.params.len);
7545 defer allocator.free(function_attributes);
7546
7547 var attributes: struct {
7548 builder: *Builder,
7549 list: std.ArrayList(Attribute.Index),
7550
7551 fn deinit(state: *@This()) void {
7552 state.list.deinit();
7553 state.* = undefined;
7554 }
7555
7556 fn get(state: *@This(), attributes: []const Attribute) Allocator.Error!Attributes {
7557 try state.list.resize(attributes.len);
7558 for (state.list.items, attributes) |*item, attribute|
7559 item.* = try state.builder.attr(attribute);
7560 return state.builder.attrs(state.list.items);
7561 }
7562 } = .{ .builder = self, .list = std.ArrayList(Attribute.Index).init(allocator) };
7563 defer attributes.deinit();
7564
7565 var overload_index: usize = 0;
7566 function_attributes[FunctionAttributes.function_index] = try attributes.get(signature.attrs);
7567 for (
7568 param_types,
7569 function_attributes[FunctionAttributes.return_index..],
7570 signature.params,
7571 ) |*param_type, *param_attributes, signature_param| {
7572 switch (signature_param.kind) {
7573 .type => |ty| param_type.* = ty,
7574 .overloaded => {
7575 param_type.* = overload[overload_index];
7576 overload_index += 1;
7577 },
7578 .overloaded_tuple => |len| {
7579 const fields = try allocator.alloc(Type, len);
7580 defer allocator.free(fields);
7581 for (fields, overload[overload_index..][0..len]) |*field, ty| field.* = ty;
7582 param_type.* = try self.structType(.normal, fields);
7583 overload_index += len;
7584 },
7585 .matches, .matches_tuple, .matches_with_overflow => {},
7586 }
7587 param_attributes.* = try attributes.get(signature_param.attrs);
7588 }
7589 assert(overload_index == overload.len);
7590 for (param_types, signature.params) |*param_type, signature_param| switch (signature_param.kind) {
7591 .type, .overloaded, .overloaded_tuple => {},
7592 .matches => |param_index| param_type.* = param_types[param_index],
7593 .matches_tuple => |tuple| param_type.* =
7594 param_types[tuple.param].structFields(self)[tuple.field],
7595 .matches_with_overflow => |param_index| {
7596 const ty = param_types[param_index];
7597 param_type.* = try self.structType(.normal, &.{ ty, try ty.changeScalar(.i1, self) });
7598 },
7599 };
7600
7601 const function_index =
7602 try self.addFunction(try self.fnType(param_types[0], param_types[1..], .normal), name);
7603 function_index.ptr(self).attributes = try self.fnAttrs(function_attributes);
7604 return function_index;
7605}
7606
68867607pub fn intConst(self: *Builder, ty: Type, value: anytype) Allocator.Error!Constant {
7608 const int_value = switch (@typeInfo(@TypeOf(value))) {
7609 .Int, .ComptimeInt => value,
7610 .Enum => @intFromEnum(value),
7611 else => @compileError("intConst expected an integral value, got " ++ @typeName(@TypeOf(value))),
7612 };
68877613 var limbs: [
6888 switch (@typeInfo(@TypeOf(value))) {
7614 switch (@typeInfo(@TypeOf(int_value))) {
68897615 .Int => |info| std.math.big.int.calcTwosCompLimbCount(info.bits),
6890 .ComptimeInt => std.math.big.int.calcLimbLen(value),
6891 else => @compileError(
6892 "intConst expected an integral value, got " ++ @typeName(@TypeOf(value)),
6893 ),
7616 .ComptimeInt => std.math.big.int.calcLimbLen(int_value),
7617 else => unreachable,
68947618 }
68957619 ]std.math.big.Limb = undefined;
6896 return self.bigIntConst(ty, std.math.big.int.Mutable.init(&limbs, value).toConst());
7620 return self.bigIntConst(ty, std.math.big.int.Mutable.init(&limbs, int_value).toConst());
68977621}
68987622
68997623pub fn intValue(self: *Builder, ty: Type, value: anytype) Allocator.Error!Value {
......@@ -7304,18 +8028,18 @@ pub fn binValue(self: *Builder, tag: Constant.Tag, lhs: Constant, rhs: Constant)
73048028pub fn asmConst(
73058029 self: *Builder,
73068030 ty: Type,
7307 info: Constant.Asm.Info,
8031 info: Constant.Assembly.Info,
73088032 assembly: String,
73098033 constraints: String,
73108034) Allocator.Error!Constant {
7311 try self.ensureUnusedConstantCapacity(1, Constant.Asm, 0);
8035 try self.ensureUnusedConstantCapacity(1, Constant.Assembly, 0);
73128036 return self.asmConstAssumeCapacity(ty, info, assembly, constraints);
73138037}
73148038
73158039pub fn asmValue(
73168040 self: *Builder,
73178041 ty: Type,
7318 info: Constant.Asm.Info,
8042 info: Constant.Assembly.Info,
73198043 assembly: String,
73208044 constraints: String,
73218045) Allocator.Error!Value {
......@@ -7413,7 +8137,7 @@ pub fn printUnbuffered(
74138137 if (variable.global.getReplacement(self) != .none) continue;
74148138 const global = variable.global.ptrConst(self);
74158139 try writer.print(
7416 \\{} ={}{}{}{}{}{}{}{} {s} {%}{ }{, }
8140 \\{} ={}{}{}{}{}{}{ }{} {s} {%}{ }{, }
74178141 \\
74188142 , .{
74198143 variable.global.fmt(self),
......@@ -7472,7 +8196,9 @@ pub fn printUnbuffered(
74728196 function.attributes.param(arg, self).fmt(self),
74738197 });
74748198 if (function.instructions.len > 0)
7475 try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)});
8199 try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
8200 else
8201 try writer.print(" %{d}", .{arg});
74768202 }
74778203 switch (global.type.functionKind(self)) {
74788204 .normal => {},
......@@ -7481,11 +8207,11 @@ pub fn printUnbuffered(
74818207 try writer.writeAll("...");
74828208 },
74838209 }
7484 try writer.print("){}{}", .{ global.unnamed_addr, global.addr_space });
8210 try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space });
74858211 if (function_attributes != .none) try writer.print(" #{d}", .{
74868212 (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
74878213 });
7488 try writer.print("{}", .{function.alignment});
8214 try writer.print("{ }", .{function.alignment});
74898215 if (function.instructions.len > 0) {
74908216 var block_incoming_len: u32 = undefined;
74918217 try writer.writeAll(" {\n");
......@@ -7735,33 +8461,6 @@ pub fn printUnbuffered(
77358461 val.fmt(function_index, self),
77368462 });
77378463 },
7738 .@"llvm.ceil.",
7739 .@"llvm.cos.",
7740 .@"llvm.exp.",
7741 .@"llvm.exp2.",
7742 .@"llvm.fabs.",
7743 .@"llvm.floor.",
7744 .@"llvm.log.",
7745 .@"llvm.log10.",
7746 .@"llvm.log2.",
7747 .@"llvm.round.",
7748 .@"llvm.sin.",
7749 .@"llvm.sqrt.",
7750 .@"llvm.trunc.",
7751 .@"llvm.bitreverse.",
7752 .@"llvm.bswap.",
7753 .@"llvm.ctpop.",
7754 => |tag| {
7755 const val: Value = @enumFromInt(instruction.data);
7756 const ty = val.typeOf(function_index, self);
7757 try writer.print(" %{} = call {%} @{s}{m}({%})\n", .{
7758 instruction_index.name(&function).fmt(self),
7759 ty.fmt(self),
7760 @tagName(tag),
7761 ty.fmt(self),
7762 val.fmt(function_index, self),
7763 });
7764 },
77658464 .getelementptr,
77668465 .@"getelementptr inbounds",
77678466 => |tag| {
......@@ -7809,41 +8508,6 @@ pub fn printUnbuffered(
78098508 for (indices) |index| try writer.print(", {d}", .{index});
78108509 try writer.writeByte('\n');
78118510 },
7812 .@"llvm.maxnum.",
7813 .@"llvm.minnum.",
7814 .@"llvm.ctlz.",
7815 .@"llvm.cttz.",
7816 .@"llvm.sadd.sat.",
7817 .@"llvm.smax.",
7818 .@"llvm.smin.",
7819 .@"llvm.smul.fix.sat.",
7820 .@"llvm.sshl.sat.",
7821 .@"llvm.ssub.sat.",
7822 .@"llvm.uadd.sat.",
7823 .@"llvm.umax.",
7824 .@"llvm.umin.",
7825 .@"llvm.umul.fix.sat.",
7826 .@"llvm.ushl.sat.",
7827 .@"llvm.usub.sat.",
7828 => |tag| {
7829 const extra =
7830 function.extraData(Function.Instruction.Binary, instruction.data);
7831 const ty = instruction_index.typeOf(function_index, self);
7832 try writer.print(" %{} = call {%} @{s}{m}({%}, {%}{s})\n", .{
7833 instruction_index.name(&function).fmt(self),
7834 ty.fmt(self),
7835 @tagName(tag),
7836 ty.fmt(self),
7837 extra.lhs.fmt(function_index, self),
7838 extra.rhs.fmt(function_index, self),
7839 switch (tag) {
7840 .@"llvm.smul.fix.sat.",
7841 .@"llvm.umul.fix.sat.",
7842 => ", i32 0",
7843 else => "",
7844 },
7845 });
7846 },
78478511 .load,
78488512 .@"load atomic",
78498513 .@"load atomic volatile",
......@@ -7984,20 +8648,6 @@ pub fn printUnbuffered(
79848648 extra.type.fmt(self),
79858649 });
79868650 },
7987 .@"llvm.fma." => |tag| {
7988 const extra =
7989 function.extraData(Function.Instruction.FusedMultiplyAdd, instruction.data);
7990 const ty = instruction_index.typeOf(function_index, self);
7991 try writer.print(" %{} = call {%} @{s}{m}({%}, {%}, {%})\n", .{
7992 instruction_index.name(&function).fmt(self),
7993 ty.fmt(self),
7994 @tagName(tag),
7995 ty.fmt(self),
7996 extra.a.fmt(function_index, self),
7997 extra.b.fmt(function_index, self),
7998 extra.c.fmt(function_index, self),
7999 });
8000 },
80018651 }
80028652 }
80038653 try writer.writeByte('}');
......@@ -9623,13 +10273,13 @@ fn binConstAssumeCapacity(
962310273fn asmConstAssumeCapacity(
962410274 self: *Builder,
962510275 ty: Type,
9626 info: Constant.Asm.Info,
10276 info: Constant.Assembly.Info,
962710277 assembly: String,
962810278 constraints: String,
962910279) Constant {
963010280 assert(ty.functionKind(self) == .normal);
963110281
9632 const Key = struct { tag: Constant.Tag, extra: Constant.Asm };
10282 const Key = struct { tag: Constant.Tag, extra: Constant.Assembly };
963310283 const Adapter = struct {
963410284 builder: *const Builder,
963510285 pub fn hash(_: @This(), key: Key) u32 {
......@@ -9641,7 +10291,7 @@ fn asmConstAssumeCapacity(
964110291 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
964210292 if (lhs_key.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false;
964310293 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
9644 const rhs_extra = ctx.builder.constantExtraData(Constant.Asm, rhs_data);
10294 const rhs_extra = ctx.builder.constantExtraData(Constant.Assembly, rhs_data);
964510295 return std.meta.eql(lhs_key.extra, rhs_extra);
964610296 }
964710297 };
src/codegen/llvm/bindings.zig-126
......@@ -345,9 +345,6 @@ pub const Value = opaque {
345345 pub const addSretAttr = ZigLLVMAddSretAttr;
346346 extern fn ZigLLVMAddSretAttr(fn_ref: *Value, type_val: *Type) void;
347347
348 pub const setCallSret = ZigLLVMSetCallSret;
349 extern fn ZigLLVMSetCallSret(Call: *Value, return_type: *Type) void;
350
351348 pub const getParam = LLVMGetParam;
352349 extern fn LLVMGetParam(Fn: *Value, Index: c_uint) *Value;
353350
......@@ -488,9 +485,6 @@ pub const Module = opaque {
488485 pub const getNamedFunction = LLVMGetNamedFunction;
489486 extern fn LLVMGetNamedFunction(*Module, Name: [*:0]const u8) ?*Value;
490487
491 pub const getIntrinsicDeclaration = LLVMGetIntrinsicDeclaration;
492 extern fn LLVMGetIntrinsicDeclaration(Mod: *Module, ID: c_uint, ParamTypes: ?[*]const *Type, ParamCount: usize) *Value;
493
494488 pub const printToString = LLVMPrintModuleToString;
495489 extern fn LLVMPrintModuleToString(*Module) [*:0]const u8;
496490
......@@ -664,18 +658,6 @@ pub const Builder = opaque {
664658 Name: [*:0]const u8,
665659 ) *Value;
666660
667 pub const buildCallOld = ZigLLVMBuildCall;
668 extern fn ZigLLVMBuildCall(
669 *Builder,
670 *Type,
671 Fn: *Value,
672 Args: [*]const *Value,
673 NumArgs: c_uint,
674 CC: CallConv,
675 attr: CallAttr,
676 Name: [*:0]const u8,
677 ) *Value;
678
679661 pub const buildRetVoid = LLVMBuildRetVoid;
680662 extern fn LLVMBuildRetVoid(*Builder) *Value;
681663
......@@ -712,12 +694,6 @@ pub const Builder = opaque {
712694 pub const buildNUWAdd = LLVMBuildNUWAdd;
713695 extern fn LLVMBuildNUWAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
714696
715 pub const buildSAddSat = ZigLLVMBuildSAddSat;
716 extern fn ZigLLVMBuildSAddSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
717
718 pub const buildUAddSat = ZigLLVMBuildUAddSat;
719 extern fn ZigLLVMBuildUAddSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
720
721697 pub const buildFSub = LLVMBuildFSub;
722698 extern fn LLVMBuildFSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
723699
......@@ -733,12 +709,6 @@ pub const Builder = opaque {
733709 pub const buildNUWSub = LLVMBuildNUWSub;
734710 extern fn LLVMBuildNUWSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
735711
736 pub const buildSSubSat = ZigLLVMBuildSSubSat;
737 extern fn ZigLLVMBuildSSubSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
738
739 pub const buildUSubSat = ZigLLVMBuildUSubSat;
740 extern fn ZigLLVMBuildUSubSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
741
742712 pub const buildFMul = LLVMBuildFMul;
743713 extern fn LLVMBuildFMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
744714
......@@ -751,12 +721,6 @@ pub const Builder = opaque {
751721 pub const buildNUWMul = LLVMBuildNUWMul;
752722 extern fn LLVMBuildNUWMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
753723
754 pub const buildSMulFixSat = ZigLLVMBuildSMulFixSat;
755 extern fn ZigLLVMBuildSMulFixSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
756
757 pub const buildUMulFixSat = ZigLLVMBuildUMulFixSat;
758 extern fn ZigLLVMBuildUMulFixSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
759
760724 pub const buildUDiv = LLVMBuildUDiv;
761725 extern fn LLVMBuildUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
762726
......@@ -799,21 +763,12 @@ pub const Builder = opaque {
799763 pub const buildNSWShl = ZigLLVMBuildNSWShl;
800764 extern fn ZigLLVMBuildNSWShl(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
801765
802 pub const buildSShlSat = ZigLLVMBuildSShlSat;
803 extern fn ZigLLVMBuildSShlSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
804
805 pub const buildUShlSat = ZigLLVMBuildUShlSat;
806 extern fn ZigLLVMBuildUShlSat(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
807
808766 pub const buildOr = LLVMBuildOr;
809767 extern fn LLVMBuildOr(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
810768
811769 pub const buildXor = LLVMBuildXor;
812770 extern fn LLVMBuildXor(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
813771
814 pub const buildIntCast2 = LLVMBuildIntCast2;
815 extern fn LLVMBuildIntCast2(*Builder, Val: *Value, DestTy: *Type, IsSigned: Bool, Name: [*:0]const u8) *Value;
816
817772 pub const buildBitCast = LLVMBuildBitCast;
818773 extern fn LLVMBuildBitCast(*Builder, Val: *Value, DestTy: *Type, Name: [*:0]const u8) *Value;
819774
......@@ -1020,81 +975,6 @@ pub const Builder = opaque {
1020975 is_volatile: bool,
1021976 ) *Value;
1022977
1023 pub const buildMaxNum = ZigLLVMBuildMaxNum;
1024 extern fn ZigLLVMBuildMaxNum(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1025
1026 pub const buildMinNum = ZigLLVMBuildMinNum;
1027 extern fn ZigLLVMBuildMinNum(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1028
1029 pub const buildCeil = ZigLLVMBuildCeil;
1030 extern fn ZigLLVMBuildCeil(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1031
1032 pub const buildCos = ZigLLVMBuildCos;
1033 extern fn ZigLLVMBuildCos(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1034
1035 pub const buildExp = ZigLLVMBuildExp;
1036 extern fn ZigLLVMBuildExp(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1037
1038 pub const buildExp2 = ZigLLVMBuildExp2;
1039 extern fn ZigLLVMBuildExp2(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1040
1041 pub const buildFAbs = ZigLLVMBuildFAbs;
1042 extern fn ZigLLVMBuildFAbs(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1043
1044 pub const buildFloor = ZigLLVMBuildFloor;
1045 extern fn ZigLLVMBuildFloor(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1046
1047 pub const buildLog = ZigLLVMBuildLog;
1048 extern fn ZigLLVMBuildLog(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1049
1050 pub const buildLog10 = ZigLLVMBuildLog10;
1051 extern fn ZigLLVMBuildLog10(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1052
1053 pub const buildLog2 = ZigLLVMBuildLog2;
1054 extern fn ZigLLVMBuildLog2(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1055
1056 pub const buildRound = ZigLLVMBuildRound;
1057 extern fn ZigLLVMBuildRound(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1058
1059 pub const buildSin = ZigLLVMBuildSin;
1060 extern fn ZigLLVMBuildSin(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1061
1062 pub const buildSqrt = ZigLLVMBuildSqrt;
1063 extern fn ZigLLVMBuildSqrt(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1064
1065 pub const buildFTrunc = ZigLLVMBuildFTrunc;
1066 extern fn ZigLLVMBuildFTrunc(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1067
1068 pub const buildBitReverse = ZigLLVMBuildBitReverse;
1069 extern fn ZigLLVMBuildBitReverse(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1070
1071 pub const buildBSwap = ZigLLVMBuildBSwap;
1072 extern fn ZigLLVMBuildBSwap(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1073
1074 pub const buildCTPop = ZigLLVMBuildCTPop;
1075 extern fn ZigLLVMBuildCTPop(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1076
1077 pub const buildCTLZ = ZigLLVMBuildCTLZ;
1078 extern fn ZigLLVMBuildCTLZ(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1079
1080 pub const buildCTTZ = ZigLLVMBuildCTTZ;
1081 extern fn ZigLLVMBuildCTTZ(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1082
1083 pub const buildFMA = ZigLLVMBuildFMA;
1084 extern fn ZigLLVMBuildFMA(builder: *Builder, a: *Value, b: *Value, c: *Value, name: [*:0]const u8) *Value;
1085
1086 pub const buildUMax = ZigLLVMBuildUMax;
1087 extern fn ZigLLVMBuildUMax(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1088
1089 pub const buildUMin = ZigLLVMBuildUMin;
1090 extern fn ZigLLVMBuildUMin(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1091
1092 pub const buildSMax = ZigLLVMBuildSMax;
1093 extern fn ZigLLVMBuildSMax(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1094
1095 pub const buildSMin = ZigLLVMBuildSMin;
1096 extern fn ZigLLVMBuildSMin(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1097
1098978 pub const buildExactUDiv = LLVMBuildExactUDiv;
1099979 extern fn LLVMBuildExactUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
1100980
......@@ -1563,9 +1443,6 @@ extern fn ZigLLVMWriteImportLibrary(
15631443 kill_at: bool,
15641444) bool;
15651445
1566pub const setCallElemTypeAttr = ZigLLVMSetCallElemTypeAttr;
1567extern fn ZigLLVMSetCallElemTypeAttr(Call: *Value, arg_index: usize, return_type: *Type) void;
1568
15691446pub const Linkage = enum(c_uint) {
15701447 External,
15711448 AvailableExternally,
......@@ -1784,9 +1661,6 @@ pub const DIGlobalVariable = opaque {
17841661pub const DIGlobalVariableExpression = opaque {
17851662 pub const getVariable = ZigLLVMGlobalGetVariable;
17861663 extern fn ZigLLVMGlobalGetVariable(global_variable: *DIGlobalVariableExpression) *DIGlobalVariable;
1787
1788 pub const getExpression = ZigLLVMGlobalGetExpression;
1789 extern fn ZigLLVMGlobalGetExpression(global_variable: *DIGlobalVariableExpression) *DIGlobalExpression;
17901664};
17911665pub const DIType = opaque {
17921666 pub const toScope = ZigLLVMTypeToScope;
src/zig_llvm.cpp+13-334
......@@ -78,30 +78,6 @@
7878
7979using namespace llvm;
8080
81void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
82 initializeLoopStrengthReducePass(*unwrap(R));
83}
84
85void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) {
86 initializeLowerIntrinsicsPass(*unwrap(R));
87}
88
89char *ZigLLVMGetHostCPUName(void) {
90 return strdup((const char *)sys::getHostCPUName().bytes_begin());
91}
92
93char *ZigLLVMGetNativeFeatures(void) {
94 SubtargetFeatures features;
95
96 StringMap<bool> host_features;
97 if (sys::getHostCPUFeatures(host_features)) {
98 for (auto &F : host_features)
99 features.AddFeature(F.first(), F.second);
100 }
101
102 return strdup((const char *)StringRef(features.getString()).bytes_begin());
103}
104
10581#ifndef NDEBUG
10682static const bool assertions_on = true;
10783#else
......@@ -179,14 +155,6 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri
179155 return reinterpret_cast<LLVMTargetMachineRef>(TM);
180156}
181157
182unsigned ZigLLVMDataLayoutGetStackAlignment(LLVMTargetDataRef TD) {
183 return unwrap(TD)->getStackAlignment().value();
184}
185
186unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
187 return unwrap(TD)->getProgramAddressSpace();
188}
189
190158namespace {
191159// LLVM's time profiler can provide a hierarchy view of the time spent
192160// in each component. It generates JSON report in Chrome's "Trace Event"
......@@ -410,12 +378,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
410378 return false;
411379}
412380
413ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) {
414 return wrap(Type::getTokenTy(*unwrap(context_ref)));
415}
416
417
418ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) {
381void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) {
419382 static OptBisect opt_bisect;
420383 opt_bisect.setLimit(limit);
421384 unwrap(context_ref)->setOptPassGate(opt_bisect);
......@@ -426,35 +389,23 @@ LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name,
426389 return wrap(func);
427390}
428391
429LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
430 LLVMValueRef *Args, unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr,
431 const char *Name)
432{
433 FunctionType *FTy = unwrap<FunctionType>(Ty);
434 CallInst *call_inst = unwrap(B)->CreateCall(FTy, unwrap(Fn),
435 ArrayRef(unwrap(Args), NumArgs), Name);
436 call_inst->setCallingConv(static_cast<CallingConv::ID>(CC));
437 switch (attr) {
438 case ZigLLVM_CallAttrAuto:
439 break;
440 case ZigLLVM_CallAttrNeverTail:
441 call_inst->setTailCallKind(CallInst::TCK_NoTail);
392void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCallKind) {
393 CallInst::TailCallKind TCK;
394 switch (TailCallKind) {
395 case ZigLLVMTailCallKindNone:
396 TCK = CallInst::TCK_None;
442397 break;
443 case ZigLLVM_CallAttrNeverInline:
444 call_inst->addFnAttr(Attribute::NoInline);
398 case ZigLLVMTailCallKindTail:
399 TCK = CallInst::TCK_Tail;
445400 break;
446 case ZigLLVM_CallAttrAlwaysTail:
447 call_inst->setTailCallKind(CallInst::TCK_MustTail);
401 case ZigLLVMTailCallKindMustTail:
402 TCK = CallInst::TCK_MustTail;
448403 break;
449 case ZigLLVM_CallAttrAlwaysInline:
450 call_inst->addFnAttr(Attribute::AlwaysInline);
404 case ZigLLVMTailCallKindNoTail:
405 TCK = CallInst::TCK_NoTail;
451406 break;
452407 }
453 return wrap(call_inst);
454}
455
456ZIG_EXTERN_C void ZigLLVMSetTailCallKind(LLVMValueRef Call, CallInst::TailCallKind TailCallKind) {
457 unwrap<CallInst>(Call)->setTailCallKind(TailCallKind);
408 unwrap<CallInst>(Call)->setTailCallKind(TCK);
458409}
459410
460411void ZigLLVMAddAttributeAtIndex(LLVMValueRef Val, unsigned Idx, LLVMAttributeRef A) {
......@@ -481,188 +432,6 @@ LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef
481432 return wrap(call_inst);
482433}
483434
484LLVMValueRef ZigLLVMBuildCeil(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
485 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::ceil, unwrap(V), nullptr, name);
486 return wrap(call_inst);
487}
488
489LLVMValueRef ZigLLVMBuildCos(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
490 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::cos, unwrap(V), nullptr, name);
491 return wrap(call_inst);
492}
493
494LLVMValueRef ZigLLVMBuildExp(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
495 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::exp, unwrap(V), nullptr, name);
496 return wrap(call_inst);
497}
498
499LLVMValueRef ZigLLVMBuildExp2(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
500 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::exp2, unwrap(V), nullptr, name);
501 return wrap(call_inst);
502}
503
504LLVMValueRef ZigLLVMBuildFAbs(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
505 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::fabs, unwrap(V), nullptr, name);
506 return wrap(call_inst);
507}
508
509LLVMValueRef ZigLLVMBuildFloor(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
510 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::floor, unwrap(V), nullptr, name);
511 return wrap(call_inst);
512}
513
514LLVMValueRef ZigLLVMBuildLog(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
515 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::log, unwrap(V), nullptr, name);
516 return wrap(call_inst);
517}
518
519LLVMValueRef ZigLLVMBuildLog10(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
520 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::log10, unwrap(V), nullptr, name);
521 return wrap(call_inst);
522}
523
524LLVMValueRef ZigLLVMBuildLog2(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
525 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::log2, unwrap(V), nullptr, name);
526 return wrap(call_inst);
527}
528
529LLVMValueRef ZigLLVMBuildRound(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
530 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::round, unwrap(V), nullptr, name);
531 return wrap(call_inst);
532}
533
534LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
535 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::sin, unwrap(V), nullptr, name);
536 return wrap(call_inst);
537}
538
539LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
540 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::sqrt, unwrap(V), nullptr, name);
541 return wrap(call_inst);
542}
543
544LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
545 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::trunc, unwrap(V), nullptr, name);
546 return wrap(call_inst);
547}
548
549LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
550 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::bitreverse, unwrap(V), nullptr, name);
551 return wrap(call_inst);
552}
553
554LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
555 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::bswap, unwrap(V), nullptr, name);
556 return wrap(call_inst);
557}
558
559LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
560 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::ctpop, unwrap(V), nullptr, name);
561 return wrap(call_inst);
562}
563
564LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
565 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ctlz, unwrap(LHS), unwrap(RHS), nullptr, name);
566 return wrap(call_inst);
567}
568
569LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
570 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::cttz, unwrap(LHS), unwrap(RHS), nullptr, name);
571 return wrap(call_inst);
572}
573
574LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char *name) {
575 llvm::Type* types[1] = {
576 unwrap(A)->getType(),
577 };
578 llvm::Value* values[3] = {unwrap(A), unwrap(B), unwrap(C)};
579
580 CallInst *call_inst = unwrap(builder)->CreateIntrinsic(Intrinsic::fma, types, values, nullptr, name);
581 return wrap(call_inst);
582}
583
584LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
585 CallInst *call_inst = unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS), name);
586 return wrap(call_inst);
587}
588
589LLVMValueRef ZigLLVMBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
590 CallInst *call_inst = unwrap(B)->CreateMinNum(unwrap(LHS), unwrap(RHS), name);
591 return wrap(call_inst);
592}
593
594LLVMValueRef ZigLLVMBuildUMax(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
595 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::umax, unwrap(LHS), unwrap(RHS), nullptr, name);
596 return wrap(call_inst);
597}
598
599LLVMValueRef ZigLLVMBuildUMin(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
600 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::umin, unwrap(LHS), unwrap(RHS), nullptr, name);
601 return wrap(call_inst);
602}
603
604LLVMValueRef ZigLLVMBuildSMax(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
605 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::smax, unwrap(LHS), unwrap(RHS), nullptr, name);
606 return wrap(call_inst);
607}
608
609LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
610 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::smin, unwrap(LHS), unwrap(RHS), nullptr, name);
611 return wrap(call_inst);
612}
613
614LLVMValueRef ZigLLVMBuildSAddSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
615 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::sadd_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
616 return wrap(call_inst);
617}
618
619LLVMValueRef ZigLLVMBuildUAddSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
620 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::uadd_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
621 return wrap(call_inst);
622}
623
624LLVMValueRef ZigLLVMBuildSSubSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
625 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ssub_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
626 return wrap(call_inst);
627}
628
629LLVMValueRef ZigLLVMBuildUSubSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
630 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::usub_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
631 return wrap(call_inst);
632}
633
634LLVMValueRef ZigLLVMBuildSMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
635 llvm::Type* types[1] = {
636 unwrap(LHS)->getType(),
637 };
638 // pass scale = 0 as third argument
639 llvm::Value* values[3] = {unwrap(LHS), unwrap(RHS), unwrap(B)->getInt32(0)};
640
641 CallInst *call_inst = unwrap(B)->CreateIntrinsic(Intrinsic::smul_fix_sat, types, values, nullptr, name);
642 return wrap(call_inst);
643}
644
645LLVMValueRef ZigLLVMBuildUMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
646 llvm::Type* types[1] = {
647 unwrap(LHS)->getType(),
648 };
649 // pass scale = 0 as third argument
650 llvm::Value* values[3] = {unwrap(LHS), unwrap(RHS), unwrap(B)->getInt32(0)};
651
652 CallInst *call_inst = unwrap(B)->CreateIntrinsic(Intrinsic::umul_fix_sat, types, values, nullptr, name);
653 return wrap(call_inst);
654}
655
656LLVMValueRef ZigLLVMBuildSShlSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
657 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::sshl_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
658 return wrap(call_inst);
659}
660
661LLVMValueRef ZigLLVMBuildUShlSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
662 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ushl_sat, unwrap(LHS), unwrap(RHS), nullptr, name);
663 return wrap(call_inst);
664}
665
666435void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {
667436 assert( isa<Function>(unwrap(fn)) );
668437 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));
......@@ -1206,14 +975,6 @@ void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val) {
1206975 func->addParamAttrs(0, attr_builder);
1207976}
1208977
1209void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty) {
1210 Function *func = unwrap<Function>(fn_ref);
1211 AttrBuilder attr_builder(func->getContext());
1212 Type *llvm_type = unwrap<Type>(elem_ty);
1213 attr_builder.addTypeAttr(Attribute::ElementType, llvm_type);
1214 func->addParamAttrs(arg_index, attr_builder);
1215}
1216
1217978void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) {
1218979 Function *func = unwrap<Function>(fn_ref);
1219980 func->addFnAttr(attr_name, attr_value);
......@@ -1223,40 +984,6 @@ void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
1223984 cl::ParseCommandLineOptions(argc, argv);
1224985}
1225986
1226const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) {
1227 return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin();
1228}
1229
1230const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) {
1231 return (const char*)Triple::getVendorTypeName((Triple::VendorType)vendor).bytes_begin();
1232}
1233
1234const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) {
1235 const char* name = (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin();
1236 if (strcmp(name, "macosx") == 0) return "macos";
1237 return name;
1238}
1239
1240const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {
1241 return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin();
1242}
1243
1244void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type,
1245 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
1246 ZigLLVM_ObjectFormatType *oformat)
1247{
1248 char *native_triple = LLVMGetDefaultTargetTriple();
1249 Triple triple(Triple::normalize(native_triple));
1250
1251 *arch_type = (ZigLLVM_ArchType)triple.getArch();
1252 *vendor_type = (ZigLLVM_VendorType)triple.getVendor();
1253 *os_type = (ZigLLVM_OSType)triple.getOS();
1254 *environ_type = (ZigLLVM_EnvironmentType)triple.getEnvironment();
1255 *oformat = (ZigLLVM_ObjectFormatType)triple.getObjectFormat();
1256
1257 free(native_triple);
1258}
1259
1260987void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module, bool produce_dwarf64) {
1261988 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
1262989 unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4);
......@@ -1314,50 +1041,6 @@ LLVMValueRef ZigLLVMBuildAllocaInAddressSpace(LLVMBuilderRef builder, LLVMTypeRe
13141041 return wrap(unwrap(builder)->CreateAlloca(unwrap(Ty), AddressSpace, nullptr, Name));
13151042}
13161043
1317void ZigLLVMSetTailCall(LLVMValueRef Call) {
1318 unwrap<CallInst>(Call)->setTailCallKind(CallInst::TCK_MustTail);
1319}
1320
1321void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type) {
1322 CallInst *call_inst = unwrap<CallInst>(Call);
1323 Type *llvm_type = unwrap<Type>(return_type);
1324 call_inst->addParamAttr(AttributeList::ReturnIndex,
1325 Attribute::getWithStructRetType(call_inst->getContext(), llvm_type));
1326}
1327
1328void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef return_type) {
1329 CallInst *call_inst = unwrap<CallInst>(Call);
1330 Type *llvm_type = unwrap<Type>(return_type);
1331 call_inst->addParamAttr(arg_index,
1332 Attribute::get(call_inst->getContext(), Attribute::ElementType, llvm_type));
1333}
1334
1335void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) {
1336 unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data));
1337}
1338
1339void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, ZigLLVM_CallingConv cc) {
1340 unwrap<Function>(function)->setCallingConv(static_cast<CallingConv::ID>(cc));
1341}
1342
1343class MyOStream: public raw_ostream {
1344 public:
1345 MyOStream(void (*_append_diagnostic)(void *, const char *, size_t), void *_context) :
1346 raw_ostream(true), append_diagnostic(_append_diagnostic), context(_context), pos(0) {
1347
1348 }
1349 void write_impl(const char *ptr, size_t len) override {
1350 append_diagnostic(context, ptr, len);
1351 pos += len;
1352 }
1353 uint64_t current_pos() const override {
1354 return pos;
1355 }
1356 void (*append_diagnostic)(void *, const char *, size_t);
1357 void *context;
1358 size_t pos;
1359};
1360
13611044bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch,
13621045 const char *output_lib_path, bool kill_at)
13631046{
......@@ -1549,10 +1232,6 @@ ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpress
15491232 return reinterpret_cast<ZigLLVMDIGlobalVariable*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getVariable());
15501233}
15511234
1552ZigLLVMDIGlobalExpression* ZigLLVMGlobalGetExpression(ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
1553 return reinterpret_cast<ZigLLVMDIGlobalExpression*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getExpression());
1554}
1555
15561235void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression) {
15571236 unwrap<GlobalVariable>(Val)->addDebugInfo(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression));
15581237}
src/zig_llvm.h+9-73
......@@ -43,13 +43,6 @@ struct ZigLLVMInsertionPoint;
4343struct ZigLLVMDINode;
4444struct ZigLLVMMDString;
4545
46ZIG_EXTERN_C void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
47ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
48
49/// Caller must free memory with LLVMDisposeMessage
50ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);
51ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);
52
5346ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
5447 char **error_message, bool is_debug,
5548 bool is_small, bool time_report, bool tsan, bool lto,
......@@ -67,13 +60,20 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co
6760 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
6861 LLVMCodeModel CodeModel, bool function_sections, enum ZigLLVMABIType float_abi, const char *abi_name);
6962
70ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref);
71
7263ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit);
7364
7465ZIG_EXTERN_C LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name,
7566 LLVMTypeRef FunctionTy, unsigned AddressSpace);
7667
68enum ZigLLVMTailCallKind {
69 ZigLLVMTailCallKindNone,
70 ZigLLVMTailCallKindTail,
71 ZigLLVMTailCallKindMustTail,
72 ZigLLVMTailCallKindNoTail,
73};
74
75ZIG_EXTERN_C void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCallKind);
76
7777enum ZigLLVM_CallingConv {
7878 ZigLLVM_C = 0,
7979 ZigLLVM_Fast = 8,
......@@ -129,10 +129,6 @@ enum ZigLLVM_CallAttr {
129129 ZigLLVM_CallAttrAlwaysTail,
130130 ZigLLVM_CallAttrAlwaysInline,
131131};
132ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMTypeRef function_type,
133 LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, enum ZigLLVM_CallingConv CC,
134 enum ZigLLVM_CallAttr attr, const char *Name);
135
136132ZIG_EXTERN_C void ZigLLVMAddAttributeAtIndex(LLVMValueRef Val, unsigned Idx, LLVMAttributeRef A);
137133
138134ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
......@@ -141,47 +137,6 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst,
141137ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Size,
142138 unsigned Align, bool isVolatile);
143139
144ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCeil(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
145ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCos(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
146ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildExp(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
147ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildExp2(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
148ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFAbs(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
149ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFloor(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
150ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLog(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
151ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLog10(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
152ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLog2(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
153ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildRound(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
154ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
155ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
156ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
157
158ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
159ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
160ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
161
162ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
163ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
164
165ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char* name);
166
167ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
168ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMinNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
169
170ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMax(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
171ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
172ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMax(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
173ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
174ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUAddSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
175ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSAddSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
176ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUSubSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
177ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSSubSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
178ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name);
179ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name);
180ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUShlSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
181ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSShlSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
182ZIG_EXTERN_C LLVMValueRef LLVMBuildVectorSplat(LLVMBuilderRef B, unsigned elem_count, LLVMValueRef V, const char *Name);
183
184
185140ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
186141 const char *name);
187142ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
......@@ -345,22 +300,15 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(struct ZigLLVMDIBu
345300 struct ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref);
346301
347302ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
348ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call);
349ZIG_EXTERN_C void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type);
350ZIG_EXTERN_C void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef return_type);
351ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data);
352ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc);
353303
354304ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
355305ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val);
356306ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val);
357ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty);
358307ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
359308
360309ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);
361310
362311ZIG_EXTERN_C ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression);
363ZIG_EXTERN_C ZigLLVMDIGlobalExpression* ZigLLVMGlobalGetExpression(ZigLLVMDIGlobalVariableExpression *global_variable_expression);
364312ZIG_EXTERN_C void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression);
365313
366314
......@@ -610,11 +558,6 @@ ZIG_EXTERN_C void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim);
610558#define ZigLLVM_DIFlags_LittleEndian (1U << 28)
611559#define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29)
612560
613ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
614ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
615ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os);
616ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi);
617
618561ZIG_EXTERN_C bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early, bool disable_output);
619562ZIG_EXTERN_C bool ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early, bool disable_output);
620563ZIG_EXTERN_C bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disable_output);
......@@ -625,11 +568,4 @@ ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **fil
625568ZIG_EXTERN_C bool ZigLLVMWriteImportLibrary(const char *def_path, const enum ZigLLVM_ArchType arch,
626569 const char *output_lib_path, bool kill_at);
627570
628ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type,
629 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
630 enum ZigLLVM_ObjectFormatType *oformat);
631
632ZIG_EXTERN_C unsigned ZigLLVMDataLayoutGetStackAlignment(LLVMTargetDataRef TD);
633ZIG_EXTERN_C unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD);
634
635571#endif