| author | |
| committer | |
| log | b63d9745b5d7413acea4f4723ac9f696e3fb8149 |
| tree | 079fb983319924b73f09fe17d0c757e252b009b7 |
| parent | 3ebf8ce9704647686a9f9654c59e0be17bc78984 |
5 files changed, 1260 insertions(+), 1371 deletions(-)
src/codegen/llvm.zig+225-475| ... | ... | @@ -4962,9 +4962,9 @@ pub const FuncGen = struct { |
| 4962 | 4962 | .mul_wrap => try self.airMulWrap(inst), |
| 4963 | 4963 | .mul_sat => try self.airMulSat(inst), |
| 4964 | 4964 | |
| 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"), | |
| 4968 | 4968 | |
| 4969 | 4969 | .div_float => try self.airDivFloat(inst, false), |
| 4970 | 4970 | .div_trunc => try self.airDivTrunc(inst, false), |
| ... | ... | @@ -4989,9 +4989,9 @@ pub const FuncGen = struct { |
| 4989 | 4989 | .rem_optimized => try self.airRem(inst, true), |
| 4990 | 4990 | .mod_optimized => try self.airMod(inst, true), |
| 4991 | 4991 | |
| 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"), | |
| 4995 | 4995 | .shl_with_overflow => try self.airShlWithOverflow(inst), |
| 4996 | 4996 | |
| 4997 | 4997 | .bit_and, .bool_and => try self.airAnd(inst), |
| ... | ... | @@ -5100,11 +5100,11 @@ pub const FuncGen = struct { |
| 5100 | 5100 | .memcpy => try self.airMemcpy(inst), |
| 5101 | 5101 | .set_union_tag => try self.airSetUnionTag(inst), |
| 5102 | 5102 | .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), | |
| 5106 | 5106 | .byte_swap => try self.airByteSwap(inst), |
| 5107 | .bit_reverse => try self.airBitOp(inst, .@"llvm.bitreverse."), | |
| 5107 | .bit_reverse => try self.airBitOp(inst, .bitreverse), | |
| 5108 | 5108 | .tag_name => try self.airTagName(inst), |
| 5109 | 5109 | .error_name => try self.airErrorName(inst), |
| 5110 | 5110 | .splat => try self.airSplat(inst), |
| ... | ... | @@ -5645,22 +5645,7 @@ pub const FuncGen = struct { |
| 5645 | 5645 | const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod)); |
| 5646 | 5646 | const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment); |
| 5647 | 5647 | |
| 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 }, ""); | |
| 5664 | 5649 | return if (isByRef(va_list_ty, mod)) |
| 5665 | 5650 | dest_list |
| 5666 | 5651 | else |
| ... | ... | @@ -5668,25 +5653,10 @@ pub const FuncGen = struct { |
| 5668 | 5653 | } |
| 5669 | 5654 | |
| 5670 | 5655 | fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5671 | const o = self.dg.object; | |
| 5672 | 5656 | 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); | |
| 5679 | 5658 | |
| 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}, ""); | |
| 5690 | 5660 | return .none; |
| 5691 | 5661 | } |
| 5692 | 5662 | |
| ... | ... | @@ -5697,28 +5667,13 @@ pub const FuncGen = struct { |
| 5697 | 5667 | const llvm_va_list_ty = try o.lowerType(va_list_ty); |
| 5698 | 5668 | |
| 5699 | 5669 | 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); | |
| 5717 | 5671 | |
| 5672 | _ = try self.wip.callIntrinsic(.va_start, &.{}, &.{dest_list}, ""); | |
| 5718 | 5673 | return if (isByRef(va_list_ty, mod)) |
| 5719 | list | |
| 5674 | dest_list | |
| 5720 | 5675 | 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, ""); | |
| 5722 | 5677 | } |
| 5723 | 5678 | |
| 5724 | 5679 | 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 { |
| 7570 | 7525 | const o = self.dg.object; |
| 7571 | 7526 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 7572 | 7527 | 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 | }, ""); | |
| 7586 | 7531 | } |
| 7587 | 7532 | |
| 7588 | 7533 | fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7589 | 7534 | const o = self.dg.object; |
| 7590 | 7535 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 7591 | 7536 | 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 | }, ""); | |
| 7607 | 7540 | } |
| 7608 | 7541 | |
| 7609 | 7542 | fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -7636,13 +7569,16 @@ pub const FuncGen = struct { |
| 7636 | 7569 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 7637 | 7570 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7638 | 7571 | 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); | |
| 7640 | 7574 | |
| 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 | ); | |
| 7646 | 7582 | } |
| 7647 | 7583 | |
| 7648 | 7584 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -7651,13 +7587,16 @@ pub const FuncGen = struct { |
| 7651 | 7587 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 7652 | 7588 | const lhs = try self.resolveInst(bin_op.lhs); |
| 7653 | 7589 | 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); | |
| 7655 | 7592 | |
| 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 | ); | |
| 7661 | 7600 | } |
| 7662 | 7601 | |
| 7663 | 7602 | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -7688,8 +7627,8 @@ pub const FuncGen = struct { |
| 7688 | 7627 | fn airSafeArithmetic( |
| 7689 | 7628 | fg: *FuncGen, |
| 7690 | 7629 | inst: Air.Inst.Index, |
| 7691 | signed_intrinsic: []const u8, | |
| 7692 | unsigned_intrinsic: []const u8, | |
| 7630 | signed_intrinsic: Builder.Intrinsic, | |
| 7631 | unsigned_intrinsic: Builder.Intrinsic, | |
| 7693 | 7632 | ) !Builder.Value { |
| 7694 | 7633 | const o = fg.dg.object; |
| 7695 | 7634 | const mod = o.module; |
| ... | ... | @@ -7699,36 +7638,19 @@ pub const FuncGen = struct { |
| 7699 | 7638 | const rhs = try fg.resolveInst(bin_op.rhs); |
| 7700 | 7639 | const inst_ty = fg.typeOfIndex(inst); |
| 7701 | 7640 | const scalar_ty = inst_ty.scalarType(mod); |
| 7702 | const is_scalar = scalar_ty.ip_index == inst_ty.ip_index; | |
| 7703 | 7641 | |
| 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; | |
| 7708 | 7643 | 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( | |
| 7728 | 7649 | fg.builder.buildOrReduce(overflow_bit.toLlvm(&fg.wip)), |
| 7729 | 7650 | &fg.wip, |
| 7730 | ), | |
| 7731 | }; | |
| 7651 | ) | |
| 7652 | else | |
| 7653 | overflow_bit; | |
| 7732 | 7654 | |
| 7733 | 7655 | const fail_block = try fg.wip.block(1, "OverflowFail"); |
| 7734 | 7656 | const ok_block = try fg.wip.block(1, "OverflowOk"); |
| ... | ... | @@ -7738,7 +7660,7 @@ pub const FuncGen = struct { |
| 7738 | 7660 | try fg.buildSimplePanic(.integer_overflow); |
| 7739 | 7661 | |
| 7740 | 7662 | fg.wip.cursor = .{ .block = ok_block }; |
| 7741 | return fg.wip.extractValue(result_struct, &.{0}, ""); | |
| 7663 | return fg.wip.extractValue(results, &.{0}, ""); | |
| 7742 | 7664 | } |
| 7743 | 7665 | |
| 7744 | 7666 | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -7759,10 +7681,12 @@ pub const FuncGen = struct { |
| 7759 | 7681 | const scalar_ty = inst_ty.scalarType(mod); |
| 7760 | 7682 | |
| 7761 | 7683 | 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 | ); | |
| 7766 | 7690 | } |
| 7767 | 7691 | |
| 7768 | 7692 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !Builder.Value { |
| ... | ... | @@ -7798,10 +7722,12 @@ pub const FuncGen = struct { |
| 7798 | 7722 | const scalar_ty = inst_ty.scalarType(mod); |
| 7799 | 7723 | |
| 7800 | 7724 | 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 | ); | |
| 7805 | 7731 | } |
| 7806 | 7732 | |
| 7807 | 7733 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !Builder.Value { |
| ... | ... | @@ -7837,10 +7763,12 @@ pub const FuncGen = struct { |
| 7837 | 7763 | const scalar_ty = inst_ty.scalarType(mod); |
| 7838 | 7764 | |
| 7839 | 7765 | 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 | ); | |
| 7844 | 7772 | } |
| 7845 | 7773 | |
| 7846 | 7774 | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !Builder.Value { |
| ... | ... | @@ -8028,8 +7956,8 @@ pub const FuncGen = struct { |
| 8028 | 7956 | fn airOverflow( |
| 8029 | 7957 | self: *FuncGen, |
| 8030 | 7958 | inst: Air.Inst.Index, |
| 8031 | signed_intrinsic: []const u8, | |
| 8032 | unsigned_intrinsic: []const u8, | |
| 7959 | signed_intrinsic: Builder.Intrinsic, | |
| 7960 | unsigned_intrinsic: Builder.Intrinsic, | |
| 8033 | 7961 | ) !Builder.Value { |
| 8034 | 7962 | const o = self.dg.object; |
| 8035 | 7963 | const mod = o.module; |
| ... | ... | @@ -8041,48 +7969,29 @@ pub const FuncGen = struct { |
| 8041 | 7969 | |
| 8042 | 7970 | const lhs_ty = self.typeOf(extra.lhs); |
| 8043 | 7971 | 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); | |
| 8047 | 7973 | |
| 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); | |
| 8049 | 7976 | const llvm_lhs_ty = try o.lowerType(lhs_ty); |
| 7977 | const results = try self.wip.callIntrinsic(intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, ""); | |
| 8050 | 7978 | |
| 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}, ""); | |
| 8072 | 7981 | |
| 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; | |
| 8075 | 7984 | |
| 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); | |
| 8079 | 7988 | { |
| 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); | |
| 8082 | 7991 | } |
| 8083 | 7992 | { |
| 8084 | 7993 | 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, ""); | |
| 8086 | 7995 | _ = try self.wip.store(.normal, overflow_bit, field_ptr, overflow_alignment); |
| 8087 | 7996 | } |
| 8088 | 7997 | |
| ... | ... | @@ -8090,9 +7999,9 @@ pub const FuncGen = struct { |
| 8090 | 7999 | } |
| 8091 | 8000 | |
| 8092 | 8001 | var fields: [2]Builder.Value = undefined; |
| 8093 | fields[result_index] = result; | |
| 8002 | fields[result_index] = result_val; | |
| 8094 | 8003 | fields[overflow_index] = overflow_bit; |
| 8095 | return self.wip.buildAggregate(llvm_dest_ty, &fields, ""); | |
| 8004 | return self.wip.buildAggregate(llvm_inst_ty, &fields, ""); | |
| 8096 | 8005 | } |
| 8097 | 8006 | |
| 8098 | 8007 | fn buildElementwiseCall( |
| ... | ... | @@ -8140,22 +8049,7 @@ pub const FuncGen = struct { |
| 8140 | 8049 | .function => |function| function, |
| 8141 | 8050 | else => unreachable, |
| 8142 | 8051 | }; |
| 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); | |
| 8159 | 8053 | } |
| 8160 | 8054 | |
| 8161 | 8055 | /// Creates a floating point comparison by lowering to the appropriate |
| ... | ... | @@ -8290,22 +8184,22 @@ pub const FuncGen = struct { |
| 8290 | 8184 | .mul => return self.wip.bin(.fmul, params[0], params[1], ""), |
| 8291 | 8185 | .div => return self.wip.bin(.fdiv, params[0], params[1], ""), |
| 8292 | 8186 | .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, ""), | |
| 8309 | 8203 | .tan => unreachable, |
| 8310 | 8204 | }; |
| 8311 | 8205 | |
| ... | ... | @@ -8499,25 +8393,27 @@ pub const FuncGen = struct { |
| 8499 | 8393 | |
| 8500 | 8394 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(lhs_ty), ""); |
| 8501 | 8395 | |
| 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 | ); | |
| 8506 | 8404 | |
| 8507 | 8405 | // LLVM langref says "If b is (statically or dynamically) equal to or |
| 8508 | 8406 | // larger than the integer bit width of the arguments, the result is a |
| 8509 | 8407 | // poison value." |
| 8510 | 8408 | // However Zig semantics says that saturating shift left can never produce |
| 8511 | 8409 | // 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); | |
| 8514 | 8410 | 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), | |
| 8517 | 8413 | ); |
| 8518 | 8414 | 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), | |
| 8521 | 8417 | ); |
| 8522 | 8418 | const in_range = try self.wip.icmp(.ult, rhs, bits, ""); |
| 8523 | 8419 | return self.wip.select(in_range, result, lhs_max, ""); |
| ... | ... | @@ -8940,90 +8836,38 @@ pub const FuncGen = struct { |
| 8940 | 8836 | |
| 8941 | 8837 | fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8942 | 8838 | _ = 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, &.{}, &.{}, ""); | |
| 8954 | 8840 | _ = try self.wip.@"unreachable"(); |
| 8955 | 8841 | return .none; |
| 8956 | 8842 | } |
| 8957 | 8843 | |
| 8958 | 8844 | fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8959 | 8845 | _ = 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, &.{}, &.{}, ""); | |
| 8971 | 8847 | return .none; |
| 8972 | 8848 | } |
| 8973 | 8849 | |
| 8974 | 8850 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 8975 | 8851 | _ = inst; |
| 8976 | 8852 | const o = self.dg.object; |
| 8977 | const mod = o.module; | |
| 8978 | 8853 | 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())) { | |
| 8981 | 8855 | // https://github.com/ziglang/zig/issues/11946 |
| 8982 | 8856 | return o.builder.intValue(llvm_usize, 0); |
| 8983 | 8857 | } |
| 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, ""); | |
| 8999 | 8862 | } |
| 9000 | 8863 | |
| 9001 | 8864 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9002 | 8865 | _ = inst; |
| 9003 | 8866 | 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), ""); | |
| 9027 | 8871 | } |
| 9028 | 8872 | |
| 9029 | 8873 | fn airFence(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -9526,26 +9370,37 @@ pub const FuncGen = struct { |
| 9526 | 9370 | return self.buildFloatOp(.neg, operand_ty, 1, .{operand}); |
| 9527 | 9371 | } |
| 9528 | 9372 | |
| 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 { | |
| 9530 | 9374 | const o = self.dg.object; |
| 9531 | 9375 | 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); | |
| 9532 | 9378 | const operand = try self.resolveInst(ty_op.operand); |
| 9533 | 9379 | |
| 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), ""); | |
| 9538 | 9388 | } |
| 9539 | 9389 | |
| 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 { | |
| 9541 | 9391 | const o = self.dg.object; |
| 9542 | 9392 | 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); | |
| 9543 | 9395 | const operand = try self.resolveInst(ty_op.operand); |
| 9544 | 9396 | |
| 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), ""); | |
| 9549 | 9404 | } |
| 9550 | 9405 | |
| 9551 | 9406 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -9556,6 +9411,7 @@ pub const FuncGen = struct { |
| 9556 | 9411 | var bits = operand_ty.intInfo(mod).bits; |
| 9557 | 9412 | assert(bits % 8 == 0); |
| 9558 | 9413 | |
| 9414 | const inst_ty = self.typeOfIndex(inst); | |
| 9559 | 9415 | var operand = try self.resolveInst(ty_op.operand); |
| 9560 | 9416 | var llvm_operand_ty = try o.lowerType(operand_ty); |
| 9561 | 9417 | |
| ... | ... | @@ -9576,10 +9432,8 @@ pub const FuncGen = struct { |
| 9576 | 9432 | bits = bits + 8; |
| 9577 | 9433 | } |
| 9578 | 9434 | |
| 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), ""); | |
| 9583 | 9437 | } |
| 9584 | 9438 | |
| 9585 | 9439 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -9609,11 +9463,7 @@ pub const FuncGen = struct { |
| 9609 | 9463 | |
| 9610 | 9464 | self.wip.cursor = .{ .block = end_block }; |
| 9611 | 9465 | 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); | |
| 9617 | 9467 | return phi.toValue(); |
| 9618 | 9468 | } |
| 9619 | 9469 | |
| ... | ... | @@ -9646,37 +9496,24 @@ pub const FuncGen = struct { |
| 9646 | 9496 | errdefer assert(o.named_enum_map.remove(enum_type.decl)); |
| 9647 | 9497 | |
| 9648 | 9498 | 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 | ); | |
| 9652 | 9503 | |
| 9653 | 9504 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 9654 | 9505 | defer attributes.deinit(&o.builder); |
| 9655 | 9506 | |
| 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)); | |
| 9663 | 9510 | |
| 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; | |
| 9678 | 9515 | |
| 9679 | var wip = try Builder.WipFunction.init(&o.builder, global.kind.function); | |
| 9516 | var wip = try Builder.WipFunction.init(&o.builder, function_index); | |
| 9680 | 9517 | defer wip.deinit(); |
| 9681 | 9518 | wip.cursor = .{ .block = try wip.block(0, "Entry") }; |
| 9682 | 9519 | |
| ... | ... | @@ -9693,13 +9530,13 @@ pub const FuncGen = struct { |
| 9693 | 9530 | try wip_switch.addCase(this_tag_int_value, named_block, &wip); |
| 9694 | 9531 | } |
| 9695 | 9532 | wip.cursor = .{ .block = named_block }; |
| 9696 | _ = try wip.ret(Builder.Constant.true.toValue()); | |
| 9533 | _ = try wip.ret(.true); | |
| 9697 | 9534 | |
| 9698 | 9535 | wip.cursor = .{ .block = unnamed_block }; |
| 9699 | _ = try wip.ret(Builder.Constant.false.toValue()); | |
| 9536 | _ = try wip.ret(.false); | |
| 9700 | 9537 | |
| 9701 | 9538 | try wip.finish(); |
| 9702 | return global.kind.function; | |
| 9539 | return function_index; | |
| 9703 | 9540 | } |
| 9704 | 9541 | |
| 9705 | 9542 | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -9730,38 +9567,27 @@ pub const FuncGen = struct { |
| 9730 | 9567 | if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function; |
| 9731 | 9568 | errdefer assert(o.decl_map.remove(enum_type.decl)); |
| 9732 | 9569 | |
| 9570 | const usize_ty = try o.lowerType(Type.usize); | |
| 9571 | const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0); | |
| 9733 | 9572 | 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 | ); | |
| 9735 | 9577 | |
| 9736 | 9578 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 9737 | 9579 | defer attributes.deinit(&o.builder); |
| 9738 | 9580 | |
| 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)); | |
| 9741 | 9584 | |
| 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; | |
| 9749 | 9589 | |
| 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); | |
| 9765 | 9591 | defer wip.deinit(); |
| 9766 | 9592 | wip.cursor = .{ .block = try wip.block(0, "Entry") }; |
| 9767 | 9593 | |
| ... | ... | @@ -9817,7 +9643,7 @@ pub const FuncGen = struct { |
| 9817 | 9643 | _ = try wip.@"unreachable"(); |
| 9818 | 9644 | |
| 9819 | 9645 | try wip.finish(); |
| 9820 | return global.kind.function; | |
| 9646 | return function_index; | |
| 9821 | 9647 | } |
| 9822 | 9648 | |
| 9823 | 9649 | fn getCmpLtErrorsLenFunction(self: *FuncGen) !Builder.Function.Index { |
| ... | ... | @@ -9826,33 +9652,23 @@ pub const FuncGen = struct { |
| 9826 | 9652 | const name = try o.builder.string(lt_errors_fn_name); |
| 9827 | 9653 | if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function; |
| 9828 | 9654 | |
| 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 | ); | |
| 9833 | 9659 | |
| 9834 | 9660 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 9835 | 9661 | defer attributes.deinit(&o.builder); |
| 9836 | 9662 | |
| 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)); | |
| 9840 | 9666 | |
| 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); | |
| 9851 | 9670 | |
| 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; | |
| 9856 | 9672 | } |
| 9857 | 9673 | |
| 9858 | 9674 | fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -10416,29 +10232,12 @@ pub const FuncGen = struct { |
| 10416 | 10232 | .data => {}, |
| 10417 | 10233 | } |
| 10418 | 10234 | |
| 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 | }, ""); | |
| 10442 | 10241 | return .none; |
| 10443 | 10242 | } |
| 10444 | 10243 | |
| ... | ... | @@ -10451,26 +10250,20 @@ pub const FuncGen = struct { |
| 10451 | 10250 | return self.wip.cast(.addrspacecast, operand, try o.lowerType(inst_ty), ""); |
| 10452 | 10251 | } |
| 10453 | 10252 | |
| 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 { | |
| 10455 | 10259 | 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"), | |
| 10460 | 10264 | else => return o.builder.intValue(.i32, default), |
| 10461 | 10265 | }; |
| 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, &.{}, &.{}, ""); | |
| 10474 | 10267 | } |
| 10475 | 10268 | |
| 10476 | 10269 | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -10480,7 +10273,7 @@ pub const FuncGen = struct { |
| 10480 | 10273 | |
| 10481 | 10274 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 10482 | 10275 | const dimension = pl_op.payload; |
| 10483 | return self.amdgcnWorkIntrinsic(dimension, 0, "llvm.amdgcn.workitem.id"); | |
| 10276 | return self.amdgcnWorkIntrinsic(dimension, 0, "amdgcn.workitem.id"); | |
| 10484 | 10277 | } |
| 10485 | 10278 | |
| 10486 | 10279 | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| ... | ... | @@ -10492,27 +10285,9 @@ pub const FuncGen = struct { |
| 10492 | 10285 | const dimension = pl_op.payload; |
| 10493 | 10286 | if (dimension >= 3) return o.builder.intValue(.i32, 1); |
| 10494 | 10287 | |
| 10495 | var attributes: Builder.FunctionAttributes.Wip = .{}; | |
| 10496 | defer attributes.deinit(&o.builder); | |
| 10497 | ||
| 10498 | 10288 | // Fetch the dispatch pointer, which points to this structure: |
| 10499 | 10289 | // 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", &.{}, &.{}, ""); | |
| 10516 | 10291 | |
| 10517 | 10292 | // Load the work_group_* member from the struct as u16. |
| 10518 | 10293 | // Just treat the dispatch pointer as an array of u16 to keep things simple. |
| ... | ... | @@ -10530,7 +10305,7 @@ pub const FuncGen = struct { |
| 10530 | 10305 | |
| 10531 | 10306 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 10532 | 10307 | const dimension = pl_op.payload; |
| 10533 | return self.amdgcnWorkIntrinsic(dimension, 0, "llvm.amdgcn.workgroup.id"); | |
| 10308 | return self.amdgcnWorkIntrinsic(dimension, 0, "amdgcn.workgroup.id"); | |
| 10534 | 10309 | } |
| 10535 | 10310 | |
| 10536 | 10311 | fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index { |
| ... | ... | @@ -10716,20 +10491,6 @@ pub const FuncGen = struct { |
| 10716 | 10491 | } |
| 10717 | 10492 | } |
| 10718 | 10493 | |
| 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 | ||
| 10733 | 10494 | /// Load a by-ref type by constructing a new alloca and performing a memcpy. |
| 10734 | 10495 | fn loadByRef( |
| 10735 | 10496 | fg: *FuncGen, |
| ... | ... | @@ -10778,7 +10539,7 @@ pub const FuncGen = struct { |
| 10778 | 10539 | |
| 10779 | 10540 | assert(info.flags.vector_index != .runtime); |
| 10780 | 10541 | 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); | |
| 10782 | 10543 | const vec_elem_ty = try o.lowerType(elem_ty); |
| 10783 | 10544 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); |
| 10784 | 10545 | |
| ... | ... | @@ -10848,7 +10609,7 @@ pub const FuncGen = struct { |
| 10848 | 10609 | |
| 10849 | 10610 | assert(info.flags.vector_index != .runtime); |
| 10850 | 10611 | 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); | |
| 10852 | 10613 | const vec_elem_ty = try o.lowerType(elem_ty); |
| 10853 | 10614 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); |
| 10854 | 10615 | |
| ... | ... | @@ -10982,26 +10743,15 @@ pub const FuncGen = struct { |
| 10982 | 10743 | else => unreachable, |
| 10983 | 10744 | }; |
| 10984 | 10745 | |
| 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 | "", | |
| 11003 | 10754 | ); |
| 11004 | return call; | |
| 11005 | 10755 | } |
| 11006 | 10756 | |
| 11007 | 10757 | 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), |
| 50 | 50 | constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb), |
| 51 | 51 | |
| 52 | 52 | pub const expected_args_len = 16; |
| 53 | pub const expected_attrs_len = 16; | |
| 53 | 54 | pub const expected_fields_len = 32; |
| 54 | 55 | pub const expected_gep_indices_len = 8; |
| 55 | 56 | pub const expected_cases_len = 8; |
| 56 | 57 | pub const expected_incoming_len = 8; |
| 58 | pub const expected_intrinsic_name_len = 64; | |
| 57 | 59 | |
| 58 | 60 | pub const Options = struct { |
| 59 | 61 | allocator: Allocator, |
| ... | ... | @@ -151,11 +153,14 @@ pub const Type = enum(u32) { |
| 151 | 153 | i80, |
| 152 | 154 | i128, |
| 153 | 155 | ptr, |
| 156 | @"ptr addrspace(4)", | |
| 154 | 157 | |
| 155 | 158 | none = std.math.maxInt(u32), |
| 156 | 159 | _, |
| 157 | 160 | |
| 158 | 161 | pub const err_int = Type.i16; |
| 162 | pub const ptr_amdgpu_constant = | |
| 163 | @field(Type, std.fmt.comptimePrint("ptr{ }", .{AddrSpace.amdgpu.constant})); | |
| 159 | 164 | |
| 160 | 165 | pub const Tag = enum(u4) { |
| 161 | 166 | simple, |
| ... | ... | @@ -391,7 +396,7 @@ pub const Type = enum(u32) { |
| 391 | 396 | .double, .i64, .x86_mmx => 64, |
| 392 | 397 | .x86_fp80, .i80 => 80, |
| 393 | 398 | .fp128, .ppc_fp128, .i128 => 128, |
| 394 | .ptr => @panic("TODO: query data layout"), | |
| 399 | .ptr, .@"ptr addrspace(4)" => @panic("TODO: query data layout"), | |
| 395 | 400 | _ => { |
| 396 | 401 | const item = builder.type_items.items[@intFromEnum(self)]; |
| 397 | 402 | return switch (item.tag) { |
| ... | ... | @@ -690,7 +695,7 @@ pub const Type = enum(u32) { |
| 690 | 695 | } |
| 691 | 696 | }, |
| 692 | 697 | .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))}), | |
| 694 | 699 | .target => { |
| 695 | 700 | var extra = data.builder.typeExtraDataTrail(Type.Target, item.data); |
| 696 | 701 | const types = extra.trail.next(extra.data.types_len, Type, data.builder); |
| ... | ... | @@ -795,6 +800,7 @@ pub const Type = enum(u32) { |
| 795 | 800 | .i80, |
| 796 | 801 | .i128, |
| 797 | 802 | .ptr, |
| 803 | .@"ptr addrspace(4)", | |
| 798 | 804 | => true, |
| 799 | 805 | .none => unreachable, |
| 800 | 806 | _ => { |
| ... | ... | @@ -1201,12 +1207,20 @@ pub const Attribute = union(Kind) { |
| 1201 | 1207 | try writer.print(",{d}", .{allocsize.num_elems}); |
| 1202 | 1208 | try writer.writeByte(')'); |
| 1203 | 1209 | }, |
| 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 | }, | |
| 1210 | 1224 | .uwtable => |uwtable| if (uwtable != .none) { |
| 1211 | 1225 | try writer.print(" {s}", .{@tagName(attribute)}); |
| 1212 | 1226 | if (uwtable != UwTable.default) try writer.print("({s})", .{@tagName(uwtable)}); |
| ... | ... | @@ -1424,12 +1438,16 @@ pub const Attribute = union(Kind) { |
| 1424 | 1438 | }; |
| 1425 | 1439 | |
| 1426 | 1440 | 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, | |
| 1430 | 1444 | _: u26 = 0, |
| 1431 | 1445 | |
| 1432 | 1446 | 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 | } | |
| 1433 | 1451 | }; |
| 1434 | 1452 | |
| 1435 | 1453 | pub const UwTable = enum(u32) { |
| ... | ... | @@ -2279,6 +2297,820 @@ pub const Variable = struct { |
| 2279 | 2297 | }; |
| 2280 | 2298 | }; |
| 2281 | 2299 | |
| 2300 | pub 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 | ||
| 2282 | 3114 | pub const Function = struct { |
| 2283 | 3115 | global: Global.Index, |
| 2284 | 3116 | call_conv: CallConv = CallConv.default, |
| ... | ... | @@ -2414,39 +3246,6 @@ pub const Function = struct { |
| 2414 | 3246 | insertelement, |
| 2415 | 3247 | insertvalue, |
| 2416 | 3248 | 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.", | |
| 2450 | 3249 | load, |
| 2451 | 3250 | @"load atomic", |
| 2452 | 3251 | @"load atomic volatile", |
| ... | ... | @@ -2575,22 +3374,6 @@ pub const Function = struct { |
| 2575 | 3374 | .@"frem fast", |
| 2576 | 3375 | .fsub, |
| 2577 | 3376 | .@"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.", | |
| 2594 | 3377 | .lshr, |
| 2595 | 3378 | .@"lshr exact", |
| 2596 | 3379 | .mul, |
| ... | ... | @@ -2710,22 +3493,6 @@ pub const Function = struct { |
| 2710 | 3493 | .changeScalarAssumeCapacity(.i1, wip.builder), |
| 2711 | 3494 | .fneg, |
| 2712 | 3495 | .@"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.", | |
| 2729 | 3496 | => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip), |
| 2730 | 3497 | .getelementptr, |
| 2731 | 3498 | .@"getelementptr inbounds", |
| ... | ... | @@ -2762,7 +3529,6 @@ pub const Function = struct { |
| 2762 | 3529 | }, |
| 2763 | 3530 | .unimplemented => @enumFromInt(instruction.data), |
| 2764 | 3531 | .va_arg => wip.extraData(VaArg, instruction.data).type, |
| 2765 | .@"llvm.fma." => wip.extraData(FusedMultiplyAdd, instruction.data).a.typeOfWip(wip), | |
| 2766 | 3532 | }; |
| 2767 | 3533 | } |
| 2768 | 3534 | |
| ... | ... | @@ -2791,22 +3557,6 @@ pub const Function = struct { |
| 2791 | 3557 | .@"frem fast", |
| 2792 | 3558 | .fsub, |
| 2793 | 3559 | .@"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.", | |
| 2810 | 3560 | .lshr, |
| 2811 | 3561 | .@"lshr exact", |
| 2812 | 3562 | .mul, |
| ... | ... | @@ -2927,22 +3677,6 @@ pub const Function = struct { |
| 2927 | 3677 | .changeScalarAssumeCapacity(.i1, builder), |
| 2928 | 3678 | .fneg, |
| 2929 | 3679 | .@"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.", | |
| 2946 | 3680 | => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder), |
| 2947 | 3681 | .getelementptr, |
| 2948 | 3682 | .@"getelementptr inbounds", |
| ... | ... | @@ -2981,7 +3715,6 @@ pub const Function = struct { |
| 2981 | 3715 | }, |
| 2982 | 3716 | .unimplemented => @enumFromInt(instruction.data), |
| 2983 | 3717 | .va_arg => function.extraData(VaArg, instruction.data).type, |
| 2984 | .@"llvm.fma." => function.extraData(FusedMultiplyAdd, instruction.data).a.typeOf(function_index, builder), | |
| 2985 | 3718 | }; |
| 2986 | 3719 | } |
| 2987 | 3720 | |
| ... | ... | @@ -3074,12 +3807,6 @@ pub const Function = struct { |
| 3074 | 3807 | mask: Value, |
| 3075 | 3808 | }; |
| 3076 | 3809 | |
| 3077 | pub const FusedMultiplyAdd = struct { | |
| 3078 | a: Value, | |
| 3079 | b: Value, | |
| 3080 | c: Value, | |
| 3081 | }; | |
| 3082 | ||
| 3083 | 3810 | pub const ExtractValue = struct { |
| 3084 | 3811 | val: Value, |
| 3085 | 3812 | indices_len: u32, |
| ... | ... | @@ -3487,24 +4214,7 @@ pub const WipFunction = struct { |
| 3487 | 4214 | switch (tag) { |
| 3488 | 4215 | .fneg, |
| 3489 | 4216 | .@"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.", | |
| 3503 | 4217 | => 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)), | |
| 3508 | 4218 | else => unreachable, |
| 3509 | 4219 | } |
| 3510 | 4220 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| ... | ... | @@ -3513,43 +4223,10 @@ pub const WipFunction = struct { |
| 3513 | 4223 | switch (tag) { |
| 3514 | 4224 | .fneg => self.llvm.builder.setFastMath(false), |
| 3515 | 4225 | .@"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 | => {}, | |
| 3533 | 4226 | else => unreachable, |
| 3534 | 4227 | } |
| 3535 | 4228 | self.llvm.instructions.appendAssumeCapacity(switch (tag) { |
| 3536 | 4229 | .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, | |
| 3553 | 4230 | else => unreachable, |
| 3554 | 4231 | }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self))); |
| 3555 | 4232 | } |
| ... | ... | @@ -3593,20 +4270,6 @@ pub const WipFunction = struct { |
| 3593 | 4270 | .@"frem fast", |
| 3594 | 4271 | .fsub, |
| 3595 | 4272 | .@"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.", | |
| 3610 | 4273 | .lshr, |
| 3611 | 4274 | .@"lshr exact", |
| 3612 | 4275 | .mul, |
| ... | ... | @@ -3627,9 +4290,6 @@ pub const WipFunction = struct { |
| 3627 | 4290 | .urem, |
| 3628 | 4291 | .xor, |
| 3629 | 4292 | => 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), | |
| 3633 | 4293 | else => unreachable, |
| 3634 | 4294 | } |
| 3635 | 4295 | try self.ensureUnusedExtraCapacity(1, Instruction.Binary, 0); |
| ... | ... | @@ -3665,22 +4325,6 @@ pub const WipFunction = struct { |
| 3665 | 4325 | .fmul, .@"fmul fast" => &llvm.Builder.buildFMul, |
| 3666 | 4326 | .frem, .@"frem fast" => &llvm.Builder.buildFRem, |
| 3667 | 4327 | .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, | |
| 3684 | 4328 | .lshr => &llvm.Builder.buildLShr, |
| 3685 | 4329 | .@"lshr exact" => &llvm.Builder.buildLShrExact, |
| 3686 | 4330 | .mul => &llvm.Builder.buildMul, |
| ... | ... | @@ -4419,7 +5063,7 @@ pub const WipFunction = struct { |
| 4419 | 5063 | self: *WipFunction, |
| 4420 | 5064 | function_attributes: FunctionAttributes, |
| 4421 | 5065 | ty: Type, |
| 4422 | kind: Constant.Asm.Info, | |
| 5066 | kind: Constant.Assembly.Info, | |
| 4423 | 5067 | assembly: String, |
| 4424 | 5068 | constraints: String, |
| 4425 | 5069 | args: []const Value, |
| ... | ... | @@ -4429,6 +5073,25 @@ pub const WipFunction = struct { |
| 4429 | 5073 | return self.call(.normal, CallConv.default, function_attributes, ty, callee, args, name); |
| 4430 | 5074 | } |
| 4431 | 5075 | |
| 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 | ||
| 4432 | 5095 | pub fn vaArg(self: *WipFunction, list: Value, ty: Type, name: []const u8) Allocator.Error!Value { |
| 4433 | 5096 | try self.ensureUnusedExtraCapacity(1, Instruction.VaArg, 0); |
| 4434 | 5097 | const instruction = try self.addInst(name, .{ |
| ... | ... | @@ -4448,29 +5111,6 @@ pub const WipFunction = struct { |
| 4448 | 5111 | return instruction.toValue(); |
| 4449 | 5112 | } |
| 4450 | 5113 | |
| 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 | ||
| 4474 | 5114 | pub const WipUnimplemented = struct { |
| 4475 | 5115 | instruction: Instruction.Index, |
| 4476 | 5116 | |
| ... | ... | @@ -4697,22 +5337,6 @@ pub const WipFunction = struct { |
| 4697 | 5337 | .@"icmp ugt", |
| 4698 | 5338 | .@"icmp ule", |
| 4699 | 5339 | .@"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.", | |
| 4716 | 5340 | .lshr, |
| 4717 | 5341 | .@"lshr exact", |
| 4718 | 5342 | .mul, |
| ... | ... | @@ -4828,22 +5452,6 @@ pub const WipFunction = struct { |
| 4828 | 5452 | .fneg, |
| 4829 | 5453 | .@"fneg fast", |
| 4830 | 5454 | .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.", | |
| 4847 | 5455 | => instruction.data = @intFromEnum(instructions.map(@enumFromInt(instruction.data))), |
| 4848 | 5456 | .getelementptr, |
| 4849 | 5457 | .@"getelementptr inbounds", |
| ... | ... | @@ -4949,14 +5557,6 @@ pub const WipFunction = struct { |
| 4949 | 5557 | .type = extra.type, |
| 4950 | 5558 | }); |
| 4951 | 5559 | }, |
| 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 | }, | |
| 4960 | 5560 | } |
| 4961 | 5561 | function.instructions.appendAssumeCapacity(instruction); |
| 4962 | 5562 | names[@intFromEnum(new_instruction_index)] = wip_name.map(if (self.builder.strip) |
| ... | ... | @@ -5627,7 +6227,7 @@ pub const Constant = enum(u32) { |
| 5627 | 6227 | rhs: Constant, |
| 5628 | 6228 | }; |
| 5629 | 6229 | |
| 5630 | pub const Asm = extern struct { | |
| 6230 | pub const Assembly = extern struct { | |
| 5631 | 6231 | type: Type, |
| 5632 | 6232 | assembly: String, |
| 5633 | 6233 | constraints: String, |
| ... | ... | @@ -5651,7 +6251,7 @@ pub const Constant = enum(u32) { |
| 5651 | 6251 | } |
| 5652 | 6252 | |
| 5653 | 6253 | pub fn toValue(self: Constant) Value { |
| 5654 | return @enumFromInt(@intFromEnum(Value.first_constant) + @intFromEnum(self)); | |
| 6254 | return @enumFromInt(Value.first_constant + @intFromEnum(self)); | |
| 5655 | 6255 | } |
| 5656 | 6256 | |
| 5657 | 6257 | pub fn typeOf(self: Constant, builder: *Builder) Type { |
| ... | ... | @@ -6139,7 +6739,7 @@ pub const Constant = enum(u32) { |
| 6139 | 6739 | .@"asm alignstack inteldialect unwind", |
| 6140 | 6740 | .@"asm sideeffect alignstack inteldialect unwind", |
| 6141 | 6741 | => |tag| { |
| 6142 | const extra = data.builder.constantExtraData(Asm, item.data); | |
| 6742 | const extra = data.builder.constantExtraData(Assembly, item.data); | |
| 6143 | 6743 | try writer.print("{s} {\"}, {\"}", .{ |
| 6144 | 6744 | @tagName(tag), |
| 6145 | 6745 | extra.assembly.fmt(data.builder), |
| ... | ... | @@ -6166,18 +6766,20 @@ pub const Constant = enum(u32) { |
| 6166 | 6766 | |
| 6167 | 6767 | pub const Value = enum(u32) { |
| 6168 | 6768 | none = std.math.maxInt(u31), |
| 6769 | false = first_constant + @intFromEnum(Constant.false), | |
| 6770 | true = first_constant + @intFromEnum(Constant.true), | |
| 6169 | 6771 | _, |
| 6170 | 6772 | |
| 6171 | const first_constant: Value = @enumFromInt(1 << 31); | |
| 6773 | const first_constant = 1 << 31; | |
| 6172 | 6774 | |
| 6173 | 6775 | pub fn unwrap(self: Value) union(enum) { |
| 6174 | 6776 | instruction: Function.Instruction.Index, |
| 6175 | 6777 | constant: Constant, |
| 6176 | 6778 | } { |
| 6177 | return if (@intFromEnum(self) < @intFromEnum(first_constant)) | |
| 6779 | return if (@intFromEnum(self) < first_constant) | |
| 6178 | 6780 | .{ .instruction = @enumFromInt(@intFromEnum(self)) } |
| 6179 | 6781 | else |
| 6180 | .{ .constant = @enumFromInt(@intFromEnum(self) - @intFromEnum(first_constant)) }; | |
| 6782 | .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) }; | |
| 6181 | 6783 | } |
| 6182 | 6784 | |
| 6183 | 6785 | pub fn typeOfWip(self: Value, wip: *const WipFunction) Type { |
| ... | ... | @@ -6349,8 +6951,11 @@ pub fn init(options: Options) InitError!Builder { |
| 6349 | 6951 | inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits| |
| 6350 | 6952 | assert(self.intTypeAssumeCapacity(bits) == |
| 6351 | 6953 | @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 | } | |
| 6354 | 6959 | } |
| 6355 | 6960 | |
| 6356 | 6961 | { |
| ... | ... | @@ -6883,17 +7488,136 @@ pub fn getGlobal(self: *const Builder, name: String) ?Global.Index { |
| 6883 | 7488 | return @enumFromInt(self.globals.getIndex(name) orelse return null); |
| 6884 | 7489 | } |
| 6885 | 7490 | |
| 7491 | pub 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 | ||
| 7499 | pub 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 | ||
| 7512 | pub 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 | ||
| 6886 | 7607 | pub 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 | }; | |
| 6887 | 7613 | var limbs: [ |
| 6888 | switch (@typeInfo(@TypeOf(value))) { | |
| 7614 | switch (@typeInfo(@TypeOf(int_value))) { | |
| 6889 | 7615 | .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, | |
| 6894 | 7618 | } |
| 6895 | 7619 | ]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()); | |
| 6897 | 7621 | } |
| 6898 | 7622 | |
| 6899 | 7623 | pub 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) |
| 7304 | 8028 | pub fn asmConst( |
| 7305 | 8029 | self: *Builder, |
| 7306 | 8030 | ty: Type, |
| 7307 | info: Constant.Asm.Info, | |
| 8031 | info: Constant.Assembly.Info, | |
| 7308 | 8032 | assembly: String, |
| 7309 | 8033 | constraints: String, |
| 7310 | 8034 | ) Allocator.Error!Constant { |
| 7311 | try self.ensureUnusedConstantCapacity(1, Constant.Asm, 0); | |
| 8035 | try self.ensureUnusedConstantCapacity(1, Constant.Assembly, 0); | |
| 7312 | 8036 | return self.asmConstAssumeCapacity(ty, info, assembly, constraints); |
| 7313 | 8037 | } |
| 7314 | 8038 | |
| 7315 | 8039 | pub fn asmValue( |
| 7316 | 8040 | self: *Builder, |
| 7317 | 8041 | ty: Type, |
| 7318 | info: Constant.Asm.Info, | |
| 8042 | info: Constant.Assembly.Info, | |
| 7319 | 8043 | assembly: String, |
| 7320 | 8044 | constraints: String, |
| 7321 | 8045 | ) Allocator.Error!Value { |
| ... | ... | @@ -7413,7 +8137,7 @@ pub fn printUnbuffered( |
| 7413 | 8137 | if (variable.global.getReplacement(self) != .none) continue; |
| 7414 | 8138 | const global = variable.global.ptrConst(self); |
| 7415 | 8139 | try writer.print( |
| 7416 | \\{} ={}{}{}{}{}{}{}{} {s} {%}{ }{, } | |
| 8140 | \\{} ={}{}{}{}{}{}{ }{} {s} {%}{ }{, } | |
| 7417 | 8141 | \\ |
| 7418 | 8142 | , .{ |
| 7419 | 8143 | variable.global.fmt(self), |
| ... | ... | @@ -7472,7 +8196,9 @@ pub fn printUnbuffered( |
| 7472 | 8196 | function.attributes.param(arg, self).fmt(self), |
| 7473 | 8197 | }); |
| 7474 | 8198 | 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}); | |
| 7476 | 8202 | } |
| 7477 | 8203 | switch (global.type.functionKind(self)) { |
| 7478 | 8204 | .normal => {}, |
| ... | ... | @@ -7481,11 +8207,11 @@ pub fn printUnbuffered( |
| 7481 | 8207 | try writer.writeAll("..."); |
| 7482 | 8208 | }, |
| 7483 | 8209 | } |
| 7484 | try writer.print("){}{}", .{ global.unnamed_addr, global.addr_space }); | |
| 8210 | try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space }); | |
| 7485 | 8211 | if (function_attributes != .none) try writer.print(" #{d}", .{ |
| 7486 | 8212 | (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index, |
| 7487 | 8213 | }); |
| 7488 | try writer.print("{}", .{function.alignment}); | |
| 8214 | try writer.print("{ }", .{function.alignment}); | |
| 7489 | 8215 | if (function.instructions.len > 0) { |
| 7490 | 8216 | var block_incoming_len: u32 = undefined; |
| 7491 | 8217 | try writer.writeAll(" {\n"); |
| ... | ... | @@ -7735,33 +8461,6 @@ pub fn printUnbuffered( |
| 7735 | 8461 | val.fmt(function_index, self), |
| 7736 | 8462 | }); |
| 7737 | 8463 | }, |
| 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 | }, | |
| 7765 | 8464 | .getelementptr, |
| 7766 | 8465 | .@"getelementptr inbounds", |
| 7767 | 8466 | => |tag| { |
| ... | ... | @@ -7809,41 +8508,6 @@ pub fn printUnbuffered( |
| 7809 | 8508 | for (indices) |index| try writer.print(", {d}", .{index}); |
| 7810 | 8509 | try writer.writeByte('\n'); |
| 7811 | 8510 | }, |
| 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 | }, | |
| 7847 | 8511 | .load, |
| 7848 | 8512 | .@"load atomic", |
| 7849 | 8513 | .@"load atomic volatile", |
| ... | ... | @@ -7984,20 +8648,6 @@ pub fn printUnbuffered( |
| 7984 | 8648 | extra.type.fmt(self), |
| 7985 | 8649 | }); |
| 7986 | 8650 | }, |
| 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 | }, | |
| 8001 | 8651 | } |
| 8002 | 8652 | } |
| 8003 | 8653 | try writer.writeByte('}'); |
| ... | ... | @@ -9623,13 +10273,13 @@ fn binConstAssumeCapacity( |
| 9623 | 10273 | fn asmConstAssumeCapacity( |
| 9624 | 10274 | self: *Builder, |
| 9625 | 10275 | ty: Type, |
| 9626 | info: Constant.Asm.Info, | |
| 10276 | info: Constant.Assembly.Info, | |
| 9627 | 10277 | assembly: String, |
| 9628 | 10278 | constraints: String, |
| 9629 | 10279 | ) Constant { |
| 9630 | 10280 | assert(ty.functionKind(self) == .normal); |
| 9631 | 10281 | |
| 9632 | const Key = struct { tag: Constant.Tag, extra: Constant.Asm }; | |
| 10282 | const Key = struct { tag: Constant.Tag, extra: Constant.Assembly }; | |
| 9633 | 10283 | const Adapter = struct { |
| 9634 | 10284 | builder: *const Builder, |
| 9635 | 10285 | pub fn hash(_: @This(), key: Key) u32 { |
| ... | ... | @@ -9641,7 +10291,7 @@ fn asmConstAssumeCapacity( |
| 9641 | 10291 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 9642 | 10292 | if (lhs_key.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false; |
| 9643 | 10293 | 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); | |
| 9645 | 10295 | return std.meta.eql(lhs_key.extra, rhs_extra); |
| 9646 | 10296 | } |
| 9647 | 10297 | }; |
src/codegen/llvm/bindings.zig-126| ... | ... | @@ -345,9 +345,6 @@ pub const Value = opaque { |
| 345 | 345 | pub const addSretAttr = ZigLLVMAddSretAttr; |
| 346 | 346 | extern fn ZigLLVMAddSretAttr(fn_ref: *Value, type_val: *Type) void; |
| 347 | 347 | |
| 348 | pub const setCallSret = ZigLLVMSetCallSret; | |
| 349 | extern fn ZigLLVMSetCallSret(Call: *Value, return_type: *Type) void; | |
| 350 | ||
| 351 | 348 | pub const getParam = LLVMGetParam; |
| 352 | 349 | extern fn LLVMGetParam(Fn: *Value, Index: c_uint) *Value; |
| 353 | 350 | |
| ... | ... | @@ -488,9 +485,6 @@ pub const Module = opaque { |
| 488 | 485 | pub const getNamedFunction = LLVMGetNamedFunction; |
| 489 | 486 | extern fn LLVMGetNamedFunction(*Module, Name: [*:0]const u8) ?*Value; |
| 490 | 487 | |
| 491 | pub const getIntrinsicDeclaration = LLVMGetIntrinsicDeclaration; | |
| 492 | extern fn LLVMGetIntrinsicDeclaration(Mod: *Module, ID: c_uint, ParamTypes: ?[*]const *Type, ParamCount: usize) *Value; | |
| 493 | ||
| 494 | 488 | pub const printToString = LLVMPrintModuleToString; |
| 495 | 489 | extern fn LLVMPrintModuleToString(*Module) [*:0]const u8; |
| 496 | 490 | |
| ... | ... | @@ -664,18 +658,6 @@ pub const Builder = opaque { |
| 664 | 658 | Name: [*:0]const u8, |
| 665 | 659 | ) *Value; |
| 666 | 660 | |
| 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 | ||
| 679 | 661 | pub const buildRetVoid = LLVMBuildRetVoid; |
| 680 | 662 | extern fn LLVMBuildRetVoid(*Builder) *Value; |
| 681 | 663 | |
| ... | ... | @@ -712,12 +694,6 @@ pub const Builder = opaque { |
| 712 | 694 | pub const buildNUWAdd = LLVMBuildNUWAdd; |
| 713 | 695 | extern fn LLVMBuildNUWAdd(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 714 | 696 | |
| 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 | ||
| 721 | 697 | pub const buildFSub = LLVMBuildFSub; |
| 722 | 698 | extern fn LLVMBuildFSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 723 | 699 | |
| ... | ... | @@ -733,12 +709,6 @@ pub const Builder = opaque { |
| 733 | 709 | pub const buildNUWSub = LLVMBuildNUWSub; |
| 734 | 710 | extern fn LLVMBuildNUWSub(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 735 | 711 | |
| 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 | ||
| 742 | 712 | pub const buildFMul = LLVMBuildFMul; |
| 743 | 713 | extern fn LLVMBuildFMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 744 | 714 | |
| ... | ... | @@ -751,12 +721,6 @@ pub const Builder = opaque { |
| 751 | 721 | pub const buildNUWMul = LLVMBuildNUWMul; |
| 752 | 722 | extern fn LLVMBuildNUWMul(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 753 | 723 | |
| 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 | ||
| 760 | 724 | pub const buildUDiv = LLVMBuildUDiv; |
| 761 | 725 | extern fn LLVMBuildUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 762 | 726 | |
| ... | ... | @@ -799,21 +763,12 @@ pub const Builder = opaque { |
| 799 | 763 | pub const buildNSWShl = ZigLLVMBuildNSWShl; |
| 800 | 764 | extern fn ZigLLVMBuildNSWShl(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 801 | 765 | |
| 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 | ||
| 808 | 766 | pub const buildOr = LLVMBuildOr; |
| 809 | 767 | extern fn LLVMBuildOr(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 810 | 768 | |
| 811 | 769 | pub const buildXor = LLVMBuildXor; |
| 812 | 770 | extern fn LLVMBuildXor(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 813 | 771 | |
| 814 | pub const buildIntCast2 = LLVMBuildIntCast2; | |
| 815 | extern fn LLVMBuildIntCast2(*Builder, Val: *Value, DestTy: *Type, IsSigned: Bool, Name: [*:0]const u8) *Value; | |
| 816 | ||
| 817 | 772 | pub const buildBitCast = LLVMBuildBitCast; |
| 818 | 773 | extern fn LLVMBuildBitCast(*Builder, Val: *Value, DestTy: *Type, Name: [*:0]const u8) *Value; |
| 819 | 774 | |
| ... | ... | @@ -1020,81 +975,6 @@ pub const Builder = opaque { |
| 1020 | 975 | is_volatile: bool, |
| 1021 | 976 | ) *Value; |
| 1022 | 977 | |
| 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 | ||
| 1098 | 978 | pub const buildExactUDiv = LLVMBuildExactUDiv; |
| 1099 | 979 | extern fn LLVMBuildExactUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value; |
| 1100 | 980 | |
| ... | ... | @@ -1563,9 +1443,6 @@ extern fn ZigLLVMWriteImportLibrary( |
| 1563 | 1443 | kill_at: bool, |
| 1564 | 1444 | ) bool; |
| 1565 | 1445 | |
| 1566 | pub const setCallElemTypeAttr = ZigLLVMSetCallElemTypeAttr; | |
| 1567 | extern fn ZigLLVMSetCallElemTypeAttr(Call: *Value, arg_index: usize, return_type: *Type) void; | |
| 1568 | ||
| 1569 | 1446 | pub const Linkage = enum(c_uint) { |
| 1570 | 1447 | External, |
| 1571 | 1448 | AvailableExternally, |
| ... | ... | @@ -1784,9 +1661,6 @@ pub const DIGlobalVariable = opaque { |
| 1784 | 1661 | pub const DIGlobalVariableExpression = opaque { |
| 1785 | 1662 | pub const getVariable = ZigLLVMGlobalGetVariable; |
| 1786 | 1663 | extern fn ZigLLVMGlobalGetVariable(global_variable: *DIGlobalVariableExpression) *DIGlobalVariable; |
| 1787 | ||
| 1788 | pub const getExpression = ZigLLVMGlobalGetExpression; | |
| 1789 | extern fn ZigLLVMGlobalGetExpression(global_variable: *DIGlobalVariableExpression) *DIGlobalExpression; | |
| 1790 | 1664 | }; |
| 1791 | 1665 | pub const DIType = opaque { |
| 1792 | 1666 | pub const toScope = ZigLLVMTypeToScope; |
src/zig_llvm.cpp+13-334| ... | ... | @@ -78,30 +78,6 @@ |
| 78 | 78 | |
| 79 | 79 | using namespace llvm; |
| 80 | 80 | |
| 81 | void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) { | |
| 82 | initializeLoopStrengthReducePass(*unwrap(R)); | |
| 83 | } | |
| 84 | ||
| 85 | void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) { | |
| 86 | initializeLowerIntrinsicsPass(*unwrap(R)); | |
| 87 | } | |
| 88 | ||
| 89 | char *ZigLLVMGetHostCPUName(void) { | |
| 90 | return strdup((const char *)sys::getHostCPUName().bytes_begin()); | |
| 91 | } | |
| 92 | ||
| 93 | char *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 | ||
| 105 | 81 | #ifndef NDEBUG |
| 106 | 82 | static const bool assertions_on = true; |
| 107 | 83 | #else |
| ... | ... | @@ -179,14 +155,6 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri |
| 179 | 155 | return reinterpret_cast<LLVMTargetMachineRef>(TM); |
| 180 | 156 | } |
| 181 | 157 | |
| 182 | unsigned ZigLLVMDataLayoutGetStackAlignment(LLVMTargetDataRef TD) { | |
| 183 | return unwrap(TD)->getStackAlignment().value(); | |
| 184 | } | |
| 185 | ||
| 186 | unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) { | |
| 187 | return unwrap(TD)->getProgramAddressSpace(); | |
| 188 | } | |
| 189 | ||
| 190 | 158 | namespace { |
| 191 | 159 | // LLVM's time profiler can provide a hierarchy view of the time spent |
| 192 | 160 | // in each component. It generates JSON report in Chrome's "Trace Event" |
| ... | ... | @@ -410,12 +378,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 410 | 378 | return false; |
| 411 | 379 | } |
| 412 | 380 | |
| 413 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { | |
| 414 | return wrap(Type::getTokenTy(*unwrap(context_ref))); | |
| 415 | } | |
| 416 | ||
| 417 | ||
| 418 | ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) { | |
| 381 | void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) { | |
| 419 | 382 | static OptBisect opt_bisect; |
| 420 | 383 | opt_bisect.setLimit(limit); |
| 421 | 384 | unwrap(context_ref)->setOptPassGate(opt_bisect); |
| ... | ... | @@ -426,35 +389,23 @@ LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, |
| 426 | 389 | return wrap(func); |
| 427 | 390 | } |
| 428 | 391 | |
| 429 | LLVMValueRef 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); | |
| 392 | void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCallKind) { | |
| 393 | CallInst::TailCallKind TCK; | |
| 394 | switch (TailCallKind) { | |
| 395 | case ZigLLVMTailCallKindNone: | |
| 396 | TCK = CallInst::TCK_None; | |
| 442 | 397 | break; |
| 443 | case ZigLLVM_CallAttrNeverInline: | |
| 444 | call_inst->addFnAttr(Attribute::NoInline); | |
| 398 | case ZigLLVMTailCallKindTail: | |
| 399 | TCK = CallInst::TCK_Tail; | |
| 445 | 400 | break; |
| 446 | case ZigLLVM_CallAttrAlwaysTail: | |
| 447 | call_inst->setTailCallKind(CallInst::TCK_MustTail); | |
| 401 | case ZigLLVMTailCallKindMustTail: | |
| 402 | TCK = CallInst::TCK_MustTail; | |
| 448 | 403 | break; |
| 449 | case ZigLLVM_CallAttrAlwaysInline: | |
| 450 | call_inst->addFnAttr(Attribute::AlwaysInline); | |
| 404 | case ZigLLVMTailCallKindNoTail: | |
| 405 | TCK = CallInst::TCK_NoTail; | |
| 451 | 406 | break; |
| 452 | 407 | } |
| 453 | return wrap(call_inst); | |
| 454 | } | |
| 455 | ||
| 456 | ZIG_EXTERN_C void ZigLLVMSetTailCallKind(LLVMValueRef Call, CallInst::TailCallKind TailCallKind) { | |
| 457 | unwrap<CallInst>(Call)->setTailCallKind(TailCallKind); | |
| 408 | unwrap<CallInst>(Call)->setTailCallKind(TCK); | |
| 458 | 409 | } |
| 459 | 410 | |
| 460 | 411 | void ZigLLVMAddAttributeAtIndex(LLVMValueRef Val, unsigned Idx, LLVMAttributeRef A) { |
| ... | ... | @@ -481,188 +432,6 @@ LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef |
| 481 | 432 | return wrap(call_inst); |
| 482 | 433 | } |
| 483 | 434 | |
| 484 | LLVMValueRef 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 | ||
| 489 | LLVMValueRef 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 | ||
| 494 | LLVMValueRef 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 | ||
| 499 | LLVMValueRef 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 | ||
| 504 | LLVMValueRef 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 | ||
| 509 | LLVMValueRef 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 | ||
| 514 | LLVMValueRef 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 | ||
| 519 | LLVMValueRef 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 | ||
| 524 | LLVMValueRef 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 | ||
| 529 | LLVMValueRef 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 | ||
| 534 | LLVMValueRef 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 | ||
| 539 | LLVMValueRef 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 | ||
| 544 | LLVMValueRef 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 | ||
| 549 | LLVMValueRef 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 | ||
| 554 | LLVMValueRef 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 | ||
| 559 | LLVMValueRef 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 | ||
| 564 | LLVMValueRef 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 | ||
| 569 | LLVMValueRef 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 | ||
| 574 | LLVMValueRef 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 | ||
| 584 | LLVMValueRef 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 | ||
| 589 | LLVMValueRef 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 | ||
| 594 | LLVMValueRef 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 | ||
| 599 | LLVMValueRef 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 | ||
| 604 | LLVMValueRef 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 | ||
| 609 | LLVMValueRef 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 | ||
| 614 | LLVMValueRef 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 | ||
| 619 | LLVMValueRef 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 | ||
| 624 | LLVMValueRef 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 | ||
| 629 | LLVMValueRef 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 | ||
| 634 | LLVMValueRef 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 | ||
| 645 | LLVMValueRef 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 | ||
| 656 | LLVMValueRef 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 | ||
| 661 | LLVMValueRef 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 | ||
| 666 | 435 | void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) { |
| 667 | 436 | assert( isa<Function>(unwrap(fn)) ); |
| 668 | 437 | Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn)); |
| ... | ... | @@ -1206,14 +975,6 @@ void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val) { |
| 1206 | 975 | func->addParamAttrs(0, attr_builder); |
| 1207 | 976 | } |
| 1208 | 977 | |
| 1209 | void 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 | ||
| 1217 | 978 | void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) { |
| 1218 | 979 | Function *func = unwrap<Function>(fn_ref); |
| 1219 | 980 | func->addFnAttr(attr_name, attr_value); |
| ... | ... | @@ -1223,40 +984,6 @@ void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) { |
| 1223 | 984 | cl::ParseCommandLineOptions(argc, argv); |
| 1224 | 985 | } |
| 1225 | 986 | |
| 1226 | const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) { | |
| 1227 | return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin(); | |
| 1228 | } | |
| 1229 | ||
| 1230 | const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { | |
| 1231 | return (const char*)Triple::getVendorTypeName((Triple::VendorType)vendor).bytes_begin(); | |
| 1232 | } | |
| 1233 | ||
| 1234 | const 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 | ||
| 1240 | const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) { | |
| 1241 | return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin(); | |
| 1242 | } | |
| 1243 | ||
| 1244 | void 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 | ||
| 1260 | 987 | void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module, bool produce_dwarf64) { |
| 1261 | 988 | unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION); |
| 1262 | 989 | unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4); |
| ... | ... | @@ -1314,50 +1041,6 @@ LLVMValueRef ZigLLVMBuildAllocaInAddressSpace(LLVMBuilderRef builder, LLVMTypeRe |
| 1314 | 1041 | return wrap(unwrap(builder)->CreateAlloca(unwrap(Ty), AddressSpace, nullptr, Name)); |
| 1315 | 1042 | } |
| 1316 | 1043 | |
| 1317 | void ZigLLVMSetTailCall(LLVMValueRef Call) { | |
| 1318 | unwrap<CallInst>(Call)->setTailCallKind(CallInst::TCK_MustTail); | |
| 1319 | } | |
| 1320 | ||
| 1321 | void 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 | ||
| 1328 | void 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 | ||
| 1335 | void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { | |
| 1336 | unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data)); | |
| 1337 | } | |
| 1338 | ||
| 1339 | void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, ZigLLVM_CallingConv cc) { | |
| 1340 | unwrap<Function>(function)->setCallingConv(static_cast<CallingConv::ID>(cc)); | |
| 1341 | } | |
| 1342 | ||
| 1343 | class 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 | ||
| 1361 | 1044 | bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch, |
| 1362 | 1045 | const char *output_lib_path, bool kill_at) |
| 1363 | 1046 | { |
| ... | ... | @@ -1549,10 +1232,6 @@ ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpress |
| 1549 | 1232 | 	return reinterpret_cast<ZigLLVMDIGlobalVariable*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getVariable()); |
| 1550 | 1233 | } |
| 1551 | 1234 | |
| 1552 | ZigLLVMDIGlobalExpression* ZigLLVMGlobalGetExpression(ZigLLVMDIGlobalVariableExpression *global_variable_expression) { | |
| 1553 | 	return reinterpret_cast<ZigLLVMDIGlobalExpression*>(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)->getExpression()); | |
| 1554 | } | |
| 1555 | ||
| 1556 | 1235 | void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression) { |
| 1557 | 1236 | 	unwrap<GlobalVariable>(Val)->addDebugInfo(reinterpret_cast<DIGlobalVariableExpression*>(global_variable_expression)); |
| 1558 | 1237 | } |
src/zig_llvm.h+9-73| ... | ... | @@ -43,13 +43,6 @@ struct ZigLLVMInsertionPoint; |
| 43 | 43 | struct ZigLLVMDINode; |
| 44 | 44 | struct ZigLLVMMDString; |
| 45 | 45 | |
| 46 | ZIG_EXTERN_C void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R); | |
| 47 | ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R); | |
| 48 | ||
| 49 | /// Caller must free memory with LLVMDisposeMessage | |
| 50 | ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void); | |
| 51 | ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void); | |
| 52 | ||
| 53 | 46 | ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 54 | 47 | char **error_message, bool is_debug, |
| 55 | 48 | bool is_small, bool time_report, bool tsan, bool lto, |
| ... | ... | @@ -67,13 +60,20 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co |
| 67 | 60 | const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, |
| 68 | 61 | LLVMCodeModel CodeModel, bool function_sections, enum ZigLLVMABIType float_abi, const char *abi_name); |
| 69 | 62 | |
| 70 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); | |
| 71 | ||
| 72 | 63 | ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit); |
| 73 | 64 | |
| 74 | 65 | ZIG_EXTERN_C LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, |
| 75 | 66 | LLVMTypeRef FunctionTy, unsigned AddressSpace); |
| 76 | 67 | |
| 68 | enum ZigLLVMTailCallKind { | |
| 69 | ZigLLVMTailCallKindNone, | |
| 70 | ZigLLVMTailCallKindTail, | |
| 71 | ZigLLVMTailCallKindMustTail, | |
| 72 | ZigLLVMTailCallKindNoTail, | |
| 73 | }; | |
| 74 | ||
| 75 | ZIG_EXTERN_C void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCallKind); | |
| 76 | ||
| 77 | 77 | enum ZigLLVM_CallingConv { |
| 78 | 78 | ZigLLVM_C = 0, |
| 79 | 79 | ZigLLVM_Fast = 8, |
| ... | ... | @@ -129,10 +129,6 @@ enum ZigLLVM_CallAttr { |
| 129 | 129 | ZigLLVM_CallAttrAlwaysTail, |
| 130 | 130 | ZigLLVM_CallAttrAlwaysInline, |
| 131 | 131 | }; |
| 132 | ZIG_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 | ||
| 136 | 132 | ZIG_EXTERN_C void ZigLLVMAddAttributeAtIndex(LLVMValueRef Val, unsigned Idx, LLVMAttributeRef A); |
| 137 | 133 | |
| 138 | 134 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, |
| ... | ... | @@ -141,47 +137,6 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, |
| 141 | 137 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Size, |
| 142 | 138 | unsigned Align, bool isVolatile); |
| 143 | 139 | |
| 144 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCeil(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 145 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCos(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 146 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildExp(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 147 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildExp2(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 148 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFAbs(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 149 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFloor(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 150 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLog(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 151 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLog10(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 152 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLog2(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 153 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildRound(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 154 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 155 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 156 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 157 | ||
| 158 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 159 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 160 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef builder, LLVMValueRef V, const char* name); | |
| 161 | ||
| 162 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 163 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 164 | ||
| 165 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char* name); | |
| 166 | ||
| 167 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 168 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMinNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 169 | ||
| 170 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMax(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 171 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 172 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMax(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 173 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMin(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 174 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUAddSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 175 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSAddSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 176 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUSubSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 177 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSSubSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 178 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name); | |
| 179 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUMulFixSat(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name); | |
| 180 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildUShlSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 181 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSShlSat(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); | |
| 182 | ZIG_EXTERN_C LLVMValueRef LLVMBuildVectorSplat(LLVMBuilderRef B, unsigned elem_count, LLVMValueRef V, const char *Name); | |
| 183 | ||
| 184 | ||
| 185 | 140 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, |
| 186 | 141 | const char *name); |
| 187 | 142 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, |
| ... | ... | @@ -345,22 +300,15 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(struct ZigLLVMDIBu |
| 345 | 300 | struct ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref); |
| 346 | 301 | |
| 347 | 302 | ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); |
| 348 | ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call); | |
| 349 | ZIG_EXTERN_C void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type); | |
| 350 | ZIG_EXTERN_C void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef return_type); | |
| 351 | ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data); | |
| 352 | ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc); | |
| 353 | 303 | |
| 354 | 304 | ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); |
| 355 | 305 | ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); |
| 356 | 306 | ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val); |
| 357 | ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty); | |
| 358 | 307 | ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); |
| 359 | 308 | |
| 360 | 309 | ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); |
| 361 | 310 | |
| 362 | 311 | ZIG_EXTERN_C ZigLLVMDIGlobalVariable* ZigLLVMGlobalGetVariable(ZigLLVMDIGlobalVariableExpression *global_variable_expression); |
| 363 | ZIG_EXTERN_C ZigLLVMDIGlobalExpression* ZigLLVMGlobalGetExpression(ZigLLVMDIGlobalVariableExpression *global_variable_expression); | |
| 364 | 312 | ZIG_EXTERN_C void ZigLLVMAttachMetaData(LLVMValueRef Val, ZigLLVMDIGlobalVariableExpression *global_variable_expression); |
| 365 | 313 | |
| 366 | 314 | |
| ... | ... | @@ -610,11 +558,6 @@ ZIG_EXTERN_C void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim); |
| 610 | 558 | #define ZigLLVM_DIFlags_LittleEndian (1U << 28) |
| 611 | 559 | #define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29) |
| 612 | 560 | |
| 613 | ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); | |
| 614 | ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); | |
| 615 | ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os); | |
| 616 | ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi); | |
| 617 | ||
| 618 | 561 | ZIG_EXTERN_C bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early, bool disable_output); |
| 619 | 562 | ZIG_EXTERN_C bool ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early, bool disable_output); |
| 620 | 563 | ZIG_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 |
| 625 | 568 | ZIG_EXTERN_C bool ZigLLVMWriteImportLibrary(const char *def_path, const enum ZigLLVM_ArchType arch, |
| 626 | 569 | const char *output_lib_path, bool kill_at); |
| 627 | 570 | |
| 628 | ZIG_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 | ||
| 632 | ZIG_EXTERN_C unsigned ZigLLVMDataLayoutGetStackAlignment(LLVMTargetDataRef TD); | |
| 633 | ZIG_EXTERN_C unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD); | |
| 634 | ||
| 635 | 571 | #endif |