| ... | ... | @@ -1,7 +1,5 @@ |
| 1 | 1 | const FuncGen = @This(); |
| 2 | 2 | |
| 3 | | pub const Error = Zcu.CodegenFailError; |
| 4 | | |
| 5 | 3 | object: *Object, |
| 6 | 4 | nav_index: InternPool.Nav.Index, |
| 7 | 5 | pt: Zcu.PerThread, |
| ... | ... | @@ -63,7 +61,17 @@ disable_intrinsics: bool, |
| 63 | 61 | /// Have we seen loads or stores involving `allowzero` pointers? |
| 64 | 62 | allowzero_access: bool, |
| 65 | 63 | |
| 66 | | fn todo(fg: *FuncGen, comptime format: []const u8, args: anytype) Error { |
| 64 | /// In general, codegen should never emit errors; we cannot report useful source locations for them |
| 65 | /// and they don't really play nicely with incremental compilation. The LLVM backend mostly obeys |
| 66 | /// this rule. Where it does not, it calls `todo` to emit an error, and results in this error set |
| 67 | /// being used for the function |
| 68 | /// |
| 69 | /// Please avoid using this error set in new code. Ideally, every fallible function in this file |
| 70 | /// should have the error set `Allocator.Error`. |
| 71 | const TodoError = Zcu.CodegenFailError; |
| 72 | |
| 73 | /// Avoid introducing new calls to this function---see documentation comment on `TodoError`. |
| 74 | fn todo(fg: *FuncGen, comptime format: []const u8, args: anytype) TodoError { |
| 67 | 75 | @branchHint(.cold); |
| 68 | 76 | return fg.pt.zcu.codegenFail( |
| 69 | 77 | fg.nav_index, |
| ... | ... | @@ -167,7 +175,11 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant { |
| 167 | 175 | } |
| 168 | 176 | } |
| 169 | 177 | |
| 170 | | pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air.CoveragePoint) Error!void { |
| 178 | fn lowerType(fg: *const FuncGen, ty: Type) Allocator.Error!Builder.Type { |
| 179 | return fg.object.lowerType(fg.pt, ty); |
| 180 | } |
| 181 | |
| 182 | pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air.CoveragePoint) TodoError!void { |
| 171 | 183 | const o = self.object; |
| 172 | 184 | const zcu = self.pt.zcu; |
| 173 | 185 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -443,13 +455,16 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air |
| 443 | 455 | |
| 444 | 456 | // Instructions which may be `noreturn`. |
| 445 | 457 | .block => res: { |
| 446 | | const res = try self.airBlock(inst); |
| 447 | | if (self.typeOfIndex(inst).isNoReturn(zcu)) return; |
| 458 | const block = self.air.unwrapBlock(inst); |
| 459 | const res = try self.lowerBlock(inst, null, block.body); |
| 460 | if (block.ty.isNoReturn(zcu)) return; |
| 448 | 461 | break :res res; |
| 449 | 462 | }, |
| 450 | 463 | .dbg_inline_block => res: { |
| 451 | | const res = try self.airDbgInlineBlock(inst); |
| 452 | | if (self.typeOfIndex(inst).isNoReturn(zcu)) return; |
| 464 | const block = self.air.unwrapDbgBlock(inst); |
| 465 | self.arg_inline_index = 0; |
| 466 | const res = try self.lowerBlock(inst, block.func, block.body); |
| 467 | if (block.ty.isNoReturn(zcu)) return; |
| 453 | 468 | break :res res; |
| 454 | 469 | }, |
| 455 | 470 | .call, .call_always_tail, .call_never_tail, .call_never_inline => |tag| res: { |
| ... | ... | @@ -479,7 +494,7 @@ fn genBodyDebugScope( |
| 479 | 494 | maybe_inline_func: ?InternPool.Index, |
| 480 | 495 | body: []const Air.Inst.Index, |
| 481 | 496 | coverage_point: Air.CoveragePoint, |
| 482 | | ) Error!void { |
| 497 | ) TodoError!void { |
| 483 | 498 | const o = self.object; |
| 484 | 499 | |
| 485 | 500 | if (self.wip.strip) return self.genBody(body, coverage_point); |
| ... | ... | @@ -508,7 +523,7 @@ fn genBodyDebugScope( |
| 508 | 523 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); |
| 509 | 524 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| 510 | 525 | |
| 511 | | self.file = try o.getDebugFile(pt, file_scope); |
| 526 | self.file = try o.getDebugFile(file_scope); |
| 512 | 527 | |
| 513 | 528 | self.base_line = zcu.navSrcLine(func.owner_nav); |
| 514 | 529 | const line_number = self.base_line + 1; |
| ... | ... | @@ -562,7 +577,7 @@ const CallAttr = enum { |
| 562 | 577 | AlwaysInline, |
| 563 | 578 | }; |
| 564 | 579 | |
| 565 | | fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !Builder.Value { |
| 580 | fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) Allocator.Error!Builder.Value { |
| 566 | 581 | const air_call = self.air.unwrapCall(inst); |
| 567 | 582 | const args = air_call.args; |
| 568 | 583 | const o = self.object; |
| ... | ... | @@ -598,7 +613,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 598 | 613 | } |
| 599 | 614 | |
| 600 | 615 | const ret_ptr = if (!sret) null else blk: { |
| 601 | | const llvm_ret_ty = try o.lowerType(pt, return_type); |
| 616 | const llvm_ret_ty = try self.lowerType(return_type); |
| 602 | 617 | try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder); |
| 603 | 618 | |
| 604 | 619 | const alignment = return_type.abiAlignment(zcu).toLlvm(); |
| ... | ... | @@ -620,7 +635,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 620 | 635 | const arg = args[it.zig_index - 1]; |
| 621 | 636 | const param_ty = self.typeOf(arg); |
| 622 | 637 | const llvm_arg = try self.resolveInst(arg); |
| 623 | | const llvm_param_ty = try o.lowerType(pt, param_ty); |
| 638 | const llvm_param_ty = try self.lowerType(param_ty); |
| 624 | 639 | if (isByRef(param_ty, zcu)) { |
| 625 | 640 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); |
| 626 | 641 | const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, ""); |
| ... | ... | @@ -649,7 +664,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 649 | 664 | const llvm_arg = try self.resolveInst(arg); |
| 650 | 665 | |
| 651 | 666 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); |
| 652 | | const param_llvm_ty = try o.lowerType(pt, param_ty); |
| 667 | const param_llvm_ty = try self.lowerType(param_ty); |
| 653 | 668 | const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment); |
| 654 | 669 | if (isByRef(param_ty, zcu)) { |
| 655 | 670 | const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, ""); |
| ... | ... | @@ -719,7 +734,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 719 | 734 | llvm_arg = ptr; |
| 720 | 735 | } |
| 721 | 736 | |
| 722 | | const float_ty = try o.lowerType(pt, aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?); |
| 737 | const float_ty = try self.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?); |
| 723 | 738 | const array_ty = try o.builder.arrayType(count, float_ty); |
| 724 | 739 | |
| 725 | 740 | const loaded = try self.wip.load(.normal, array_ty, llvm_arg, alignment, ""); |
| ... | ... | @@ -760,7 +775,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 760 | 775 | .byref => { |
| 761 | 776 | const param_index = it.zig_index - 1; |
| 762 | 777 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 763 | | const param_llvm_ty = try o.lowerType(pt, param_ty); |
| 778 | const param_llvm_ty = try self.lowerType(param_ty); |
| 764 | 779 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); |
| 765 | 780 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); |
| 766 | 781 | }, |
| ... | ... | @@ -812,7 +827,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 812 | 827 | }, |
| 813 | 828 | toLlvmCallConvTag(fn_info.cc, target).?, |
| 814 | 829 | try attributes.finish(&o.builder), |
| 815 | | try o.lowerType(pt, zig_fn_ty), |
| 830 | try self.lowerType(zig_fn_ty), |
| 816 | 831 | llvm_fn, |
| 817 | 832 | llvm_args.items, |
| 818 | 833 | "", |
| ... | ... | @@ -826,7 +841,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 826 | 841 | return .none; |
| 827 | 842 | } |
| 828 | 843 | |
| 829 | | const llvm_ret_ty = try o.lowerType(pt, return_type); |
| 844 | const llvm_ret_ty = try self.lowerType(return_type); |
| 830 | 845 | if (ret_ptr) |rp| { |
| 831 | 846 | if (isByRef(return_type, zcu)) { |
| 832 | 847 | return rp; |
| ... | ... | @@ -864,7 +879,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 864 | 879 | } |
| 865 | 880 | } |
| 866 | 881 | |
| 867 | | fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void { |
| 882 | fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) Allocator.Error!void { |
| 868 | 883 | const o = fg.object; |
| 869 | 884 | const pt = fg.pt; |
| 870 | 885 | const zcu = pt.zcu; |
| ... | ... | @@ -888,7 +903,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void { |
| 888 | 903 | _ = try fg.wip.@"unreachable"(); |
| 889 | 904 | } |
| 890 | 905 | |
| 891 | | fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 906 | fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!void { |
| 892 | 907 | const o = self.object; |
| 893 | 908 | const pt = self.pt; |
| 894 | 909 | const zcu = pt.zcu; |
| ... | ... | @@ -910,7 +925,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 910 | 925 | // https://github.com/ziglang/zig/issues/15337 |
| 911 | 926 | break :undef; |
| 912 | 927 | } |
| 913 | | const len = try o.builder.intValue(try o.lowerType(pt, Type.usize), ret_ty.abiSize(zcu)); |
| 928 | const len = try o.builder.intValue(try self.lowerType(.usize), ret_ty.abiSize(zcu)); |
| 914 | 929 | _ = try self.wip.callMemSet( |
| 915 | 930 | self.ret_ptr, |
| 916 | 931 | ptr_ty.ptrAlignment(zcu).toLlvm(), |
| ... | ... | @@ -946,7 +961,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 946 | 961 | // Functions with an empty error set are emitted with an error code |
| 947 | 962 | // return type and return zero so they can be function pointers coerced |
| 948 | 963 | // to functions that return anyerror. |
| 949 | | _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(pt), 0)); |
| 964 | _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0)); |
| 950 | 965 | } else { |
| 951 | 966 | _ = try self.wip.retVoid(); |
| 952 | 967 | } |
| ... | ... | @@ -961,7 +976,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 961 | 976 | if (val_is_undef and safety) { |
| 962 | 977 | const llvm_ret_ty = operand.typeOfWip(&self.wip); |
| 963 | 978 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); |
| 964 | | const len = try o.builder.intValue(try o.lowerType(pt, Type.usize), ret_ty.abiSize(zcu)); |
| 979 | const len = try o.builder.intValue(try self.lowerType(Type.usize), ret_ty.abiSize(zcu)); |
| 965 | 980 | _ = try self.wip.callMemSet( |
| 966 | 981 | rp, |
| 967 | 982 | alignment, |
| ... | ... | @@ -997,7 +1012,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 997 | 1012 | return; |
| 998 | 1013 | } |
| 999 | 1014 | |
| 1000 | | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1015 | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 1001 | 1016 | const o = self.object; |
| 1002 | 1017 | const pt = self.pt; |
| 1003 | 1018 | const zcu = pt.zcu; |
| ... | ... | @@ -1011,7 +1026,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1011 | 1026 | // Functions with an empty error set are emitted with an error code |
| 1012 | 1027 | // return type and return zero so they can be function pointers coerced |
| 1013 | 1028 | // to functions that return anyerror. |
| 1014 | | _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(pt), 0)); |
| 1029 | _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0)); |
| 1015 | 1030 | } else { |
| 1016 | 1031 | _ = try self.wip.retVoid(); |
| 1017 | 1032 | } |
| ... | ... | @@ -1028,25 +1043,22 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1028 | 1043 | return; |
| 1029 | 1044 | } |
| 1030 | 1045 | |
| 1031 | | fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1032 | | const o = self.object; |
| 1033 | | const pt = self.pt; |
| 1046 | fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1034 | 1047 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1035 | 1048 | const list = try self.resolveInst(ty_op.operand); |
| 1036 | 1049 | const arg_ty = ty_op.ty.toType(); |
| 1037 | | const llvm_arg_ty = try o.lowerType(pt, arg_ty); |
| 1050 | const llvm_arg_ty = try self.lowerType(arg_ty); |
| 1038 | 1051 | |
| 1039 | 1052 | return self.wip.vaArg(list, llvm_arg_ty, ""); |
| 1040 | 1053 | } |
| 1041 | 1054 | |
| 1042 | | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1043 | | const o = self.object; |
| 1055 | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1044 | 1056 | const pt = self.pt; |
| 1045 | 1057 | const zcu = pt.zcu; |
| 1046 | 1058 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1047 | 1059 | const src_list = try self.resolveInst(ty_op.operand); |
| 1048 | 1060 | const va_list_ty = ty_op.ty.toType(); |
| 1049 | | const llvm_va_list_ty = try o.lowerType(pt, va_list_ty); |
| 1061 | const llvm_va_list_ty = try self.lowerType(va_list_ty); |
| 1050 | 1062 | |
| 1051 | 1063 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); |
| 1052 | 1064 | const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment); |
| ... | ... | @@ -1058,7 +1070,7 @@ fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1058 | 1070 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); |
| 1059 | 1071 | } |
| 1060 | 1072 | |
| 1061 | | fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1073 | fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1062 | 1074 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 1063 | 1075 | const src_list = try self.resolveInst(un_op); |
| 1064 | 1076 | |
| ... | ... | @@ -1066,12 +1078,11 @@ fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1066 | 1078 | return .none; |
| 1067 | 1079 | } |
| 1068 | 1080 | |
| 1069 | | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1070 | | const o = self.object; |
| 1081 | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1071 | 1082 | const pt = self.pt; |
| 1072 | 1083 | const zcu = pt.zcu; |
| 1073 | 1084 | const va_list_ty = self.typeOfIndex(inst); |
| 1074 | | const llvm_va_list_ty = try o.lowerType(pt, va_list_ty); |
| 1085 | const llvm_va_list_ty = try self.lowerType(va_list_ty); |
| 1075 | 1086 | |
| 1076 | 1087 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); |
| 1077 | 1088 | const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment); |
| ... | ... | @@ -1088,7 +1099,7 @@ fn airCmp( |
| 1088 | 1099 | inst: Air.Inst.Index, |
| 1089 | 1100 | op: math.CompareOperator, |
| 1090 | 1101 | fast: Builder.FastMathKind, |
| 1091 | | ) !Builder.Value { |
| 1102 | ) Allocator.Error!Builder.Value { |
| 1092 | 1103 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 1093 | 1104 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1094 | 1105 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -1097,7 +1108,7 @@ fn airCmp( |
| 1097 | 1108 | return self.cmp(fast, op, operand_ty, lhs, rhs); |
| 1098 | 1109 | } |
| 1099 | 1110 | |
| 1100 | | fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 1111 | fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 1101 | 1112 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1102 | 1113 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| 1103 | 1114 | |
| ... | ... | @@ -1109,21 +1120,20 @@ fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind |
| 1109 | 1120 | return self.cmp(fast, cmp_op, vec_ty, lhs, rhs); |
| 1110 | 1121 | } |
| 1111 | 1122 | |
| 1112 | | fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1123 | fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1113 | 1124 | const o = self.object; |
| 1114 | | const pt = self.pt; |
| 1115 | 1125 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 1116 | 1126 | const operand = try self.resolveInst(un_op); |
| 1117 | | const llvm_fn = try o.getCmpLtErrorsLenFunction(pt); |
| 1118 | | return self.wip.call( |
| 1127 | const errors_len_ptr = try o.getErrorsLen(); |
| 1128 | const errors_len_val = try self.wip.load( |
| 1119 | 1129 | .normal, |
| 1120 | | .fastcc, |
| 1121 | | .none, |
| 1122 | | llvm_fn.typeOf(&o.builder), |
| 1123 | | llvm_fn.toValue(&o.builder), |
| 1124 | | &.{operand}, |
| 1130 | try o.errorIntType(), |
| 1131 | errors_len_ptr.toValue(&o.builder), |
| 1132 | Type.errorAbiAlignment(o.zcu).toLlvm(), |
| 1125 | 1133 | "", |
| 1126 | 1134 | ); |
| 1135 | // Despite the name, this instruction is actually lte. MLUGG TODO RENAME |
| 1136 | return self.wip.icmp(.ule, operand, errors_len_val, ""); |
| 1127 | 1137 | } |
| 1128 | 1138 | |
| 1129 | 1139 | fn cmp( |
| ... | ... | @@ -1228,18 +1238,12 @@ fn cmp( |
| 1228 | 1238 | return self.wip.icmp(cond, lhs, rhs, ""); |
| 1229 | 1239 | } |
| 1230 | 1240 | |
| 1231 | | fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1232 | | const block = self.air.unwrapBlock(inst); |
| 1233 | | return self.lowerBlock(inst, null, block.body); |
| 1234 | | } |
| 1235 | | |
| 1236 | 1241 | fn lowerBlock( |
| 1237 | 1242 | self: *FuncGen, |
| 1238 | 1243 | inst: Air.Inst.Index, |
| 1239 | 1244 | maybe_inline_func: ?InternPool.Index, |
| 1240 | 1245 | body: []const Air.Inst.Index, |
| 1241 | | ) !Builder.Value { |
| 1242 | | const o = self.object; |
| 1246 | ) TodoError!Builder.Value { |
| 1243 | 1247 | const pt = self.pt; |
| 1244 | 1248 | const zcu = pt.zcu; |
| 1245 | 1249 | const inst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -1267,7 +1271,7 @@ fn lowerBlock( |
| 1267 | 1271 | |
| 1268 | 1272 | // Create a phi node only if the block returns a value. |
| 1269 | 1273 | if (have_block_result) { |
| 1270 | | const raw_llvm_ty = try o.lowerType(pt, inst_ty); |
| 1274 | const raw_llvm_ty = try self.lowerType(inst_ty); |
| 1271 | 1275 | const llvm_ty: Builder.Type = ty: { |
| 1272 | 1276 | // If the zig tag type is a function, this represents an actual function body; not |
| 1273 | 1277 | // a pointer to it. LLVM IR allows the call instruction to use function bodies instead |
| ... | ... | @@ -1289,7 +1293,7 @@ fn lowerBlock( |
| 1289 | 1293 | } |
| 1290 | 1294 | } |
| 1291 | 1295 | |
| 1292 | | fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1296 | fn airBr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 1293 | 1297 | const zcu = self.pt.zcu; |
| 1294 | 1298 | const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 1295 | 1299 | const block = self.blocks.get(branch.block_inst).?; |
| ... | ... | @@ -1306,7 +1310,7 @@ fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1306 | 1310 | _ = try self.wip.br(block.parent_bb); |
| 1307 | 1311 | } |
| 1308 | 1312 | |
| 1309 | | fn airRepeat(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1313 | fn airRepeat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 1310 | 1314 | const repeat = self.air.instructions.items(.data)[@intFromEnum(inst)].repeat; |
| 1311 | 1315 | const loop_bb = self.loops.get(repeat.loop_inst).?; |
| 1312 | 1316 | loop_bb.ptr(&self.wip).incoming += 1; |
| ... | ... | @@ -1318,7 +1322,7 @@ fn lowerSwitchDispatch( |
| 1318 | 1322 | switch_inst: Air.Inst.Index, |
| 1319 | 1323 | cond_ref: Air.Inst.Ref, |
| 1320 | 1324 | dispatch_info: SwitchDispatchInfo, |
| 1321 | | ) !void { |
| 1325 | ) Allocator.Error!void { |
| 1322 | 1326 | const o = self.object; |
| 1323 | 1327 | const pt = self.pt; |
| 1324 | 1328 | const zcu = pt.zcu; |
| ... | ... | @@ -1384,7 +1388,7 @@ fn lowerSwitchDispatch( |
| 1384 | 1388 | const table_index = try self.wip.conv( |
| 1385 | 1389 | .unsigned, |
| 1386 | 1390 | try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""), |
| 1387 | | try o.lowerType(pt, .usize), |
| 1391 | try self.lowerType(.usize), |
| 1388 | 1392 | "", |
| 1389 | 1393 | ); |
| 1390 | 1394 | const target_ptr_ptr = try self.ptraddScaled( |
| ... | ... | @@ -1409,7 +1413,7 @@ fn lowerSwitchDispatch( |
| 1409 | 1413 | // The switch prongs will correspond to our scalar cases. Ranges will |
| 1410 | 1414 | // be handled by conditional branches in the `else` prong. |
| 1411 | 1415 | |
| 1412 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 1416 | const llvm_usize = try self.lowerType(Type.usize); |
| 1413 | 1417 | const cond_int = if (cond.typeOfWip(&self.wip).isPointer(&o.builder)) |
| 1414 | 1418 | try self.wip.cast(.ptrtoint, cond, llvm_usize, "") |
| 1415 | 1419 | else |
| ... | ... | @@ -1501,13 +1505,13 @@ fn lowerSwitchDispatch( |
| 1501 | 1505 | } |
| 1502 | 1506 | } |
| 1503 | 1507 | |
| 1504 | | fn airSwitchDispatch(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1508 | fn airSwitchDispatch(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 1505 | 1509 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 1506 | 1510 | const dispatch_info = self.switch_dispatch_info.get(br.block_inst).?; |
| 1507 | 1511 | return self.lowerSwitchDispatch(br.block_inst, br.operand, dispatch_info); |
| 1508 | 1512 | } |
| 1509 | 1513 | |
| 1510 | | fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1514 | fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) TodoError!void { |
| 1511 | 1515 | const cond_br = self.air.unwrapCondBr(inst); |
| 1512 | 1516 | const cond = try self.resolveInst(cond_br.condition); |
| 1513 | 1517 | const then_body = cond_br.then_body; |
| ... | ... | @@ -1567,7 +1571,7 @@ fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1567 | 1571 | // No need to reset the insert cursor since this instruction is noreturn. |
| 1568 | 1572 | } |
| 1569 | 1573 | |
| 1570 | | fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { |
| 1574 | fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) TodoError!Builder.Value { |
| 1571 | 1575 | const unwrapped_try = self.air.unwrapTry(inst); |
| 1572 | 1576 | const err_union = try self.resolveInst(unwrapped_try.error_union); |
| 1573 | 1577 | const body = unwrapped_try.else_body; |
| ... | ... | @@ -1576,7 +1580,7 @@ fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { |
| 1576 | 1580 | return lowerTry(self, err_union, body, err_union_ty, false, .none, is_unused, err_cold); |
| 1577 | 1581 | } |
| 1578 | 1582 | |
| 1579 | | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { |
| 1583 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) TodoError!Builder.Value { |
| 1580 | 1584 | const zcu = self.pt.zcu; |
| 1581 | 1585 | const unwrapped_try = self.air.unwrapTryPtr(inst); |
| 1582 | 1586 | const err_union_ptr = try self.resolveInst(unwrapped_try.error_union_ptr); |
| ... | ... | @@ -1599,13 +1603,13 @@ fn lowerTry( |
| 1599 | 1603 | operand_ptr_align: InternPool.Alignment, |
| 1600 | 1604 | is_unused: bool, |
| 1601 | 1605 | err_cold: bool, |
| 1602 | | ) !Builder.Value { |
| 1606 | ) TodoError!Builder.Value { |
| 1603 | 1607 | const o = fg.object; |
| 1604 | 1608 | const pt = fg.pt; |
| 1605 | 1609 | const zcu = pt.zcu; |
| 1606 | 1610 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 1607 | 1611 | const payload_has_bits = payload_ty.hasRuntimeBits(zcu); |
| 1608 | | const error_type = try o.errorIntType(pt); |
| 1612 | const error_type = try o.errorIntType(); |
| 1609 | 1613 | |
| 1610 | 1614 | const err_set_align: InternPool.Alignment, const payload_align: InternPool.Alignment = if (operand_is_ptr) .{ |
| 1611 | 1615 | operand_ptr_align.minStrict(Type.anyerror.abiAlignment(zcu)), |
| ... | ... | @@ -1657,11 +1661,11 @@ fn lowerTry( |
| 1657 | 1661 | } else if (isByRef(payload_ty, zcu)) { |
| 1658 | 1662 | return fg.loadByRef(payload_ptr, payload_ty, payload_align.toLlvm(), .normal); |
| 1659 | 1663 | } else { |
| 1660 | | return fg.wip.load(.normal, try o.lowerType(pt, payload_ty), payload_ptr, payload_align.toLlvm(), ""); |
| 1664 | return fg.wip.load(.normal, try fg.lowerType(payload_ty), payload_ptr, payload_align.toLlvm(), ""); |
| 1661 | 1665 | } |
| 1662 | 1666 | } |
| 1663 | 1667 | |
| 1664 | | fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) !void { |
| 1668 | fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) TodoError!void { |
| 1665 | 1669 | const o = self.object; |
| 1666 | 1670 | const pt = self.pt; |
| 1667 | 1671 | const zcu = pt.zcu; |
| ... | ... | @@ -1909,7 +1913,7 @@ fn switchCaseItemRange(self: *FuncGen, switch_br: Air.UnwrappedSwitch) ?[2]Value |
| 1909 | 1913 | return .{ min.?, max.? }; |
| 1910 | 1914 | } |
| 1911 | 1915 | |
| 1912 | | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1916 | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) TodoError!void { |
| 1913 | 1917 | const block = self.air.unwrapBlock(inst); |
| 1914 | 1918 | const body = block.body; |
| 1915 | 1919 | const loop_block = try self.wip.block(1, "Loop"); // `airRepeat` will increment incoming each time |
| ... | ... | @@ -1922,21 +1926,21 @@ fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1922 | 1926 | try self.genBodyDebugScope(null, body, .none); |
| 1923 | 1927 | } |
| 1924 | 1928 | |
| 1925 | | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1929 | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1926 | 1930 | const o = self.object; |
| 1927 | 1931 | const pt = self.pt; |
| 1928 | 1932 | const zcu = pt.zcu; |
| 1929 | 1933 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1930 | 1934 | const operand_ty = self.typeOf(ty_op.operand); |
| 1931 | 1935 | const array_ty = operand_ty.childType(zcu); |
| 1932 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 1936 | const llvm_usize = try self.lowerType(.usize); |
| 1933 | 1937 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu)); |
| 1934 | | const slice_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst)); |
| 1938 | const slice_llvm_ty = try self.lowerType(self.typeOfIndex(inst)); |
| 1935 | 1939 | const operand = try self.resolveInst(ty_op.operand); |
| 1936 | 1940 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); |
| 1937 | 1941 | } |
| 1938 | 1942 | |
| 1939 | | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1943 | fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 1940 | 1944 | const o = self.object; |
| 1941 | 1945 | const pt = self.pt; |
| 1942 | 1946 | const zcu = pt.zcu; |
| ... | ... | @@ -1949,7 +1953,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1949 | 1953 | |
| 1950 | 1954 | const dest_ty = self.typeOfIndex(inst); |
| 1951 | 1955 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 1952 | | const dest_llvm_ty = try o.lowerType(pt, dest_ty); |
| 1956 | const dest_llvm_ty = try self.lowerType(dest_ty); |
| 1953 | 1957 | const target = zcu.getTarget(); |
| 1954 | 1958 | |
| 1955 | 1959 | if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv( |
| ... | ... | @@ -1987,7 +1991,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1987 | 1991 | extended = try self.wip.cast(.bitcast, extended, param_type, ""); |
| 1988 | 1992 | } |
| 1989 | 1993 | |
| 1990 | | const libc_fn = try self.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty); |
| 1994 | const libc_fn = try o.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty); |
| 1991 | 1995 | return self.wip.call( |
| 1992 | 1996 | .normal, |
| 1993 | 1997 | .ccc, |
| ... | ... | @@ -2003,7 +2007,7 @@ fn airIntFromFloat( |
| 2003 | 2007 | self: *FuncGen, |
| 2004 | 2008 | inst: Air.Inst.Index, |
| 2005 | 2009 | fast: Builder.FastMathKind, |
| 2006 | | ) !Builder.Value { |
| 2010 | ) TodoError!Builder.Value { |
| 2007 | 2011 | _ = fast; |
| 2008 | 2012 | |
| 2009 | 2013 | const o = self.object; |
| ... | ... | @@ -2018,7 +2022,7 @@ fn airIntFromFloat( |
| 2018 | 2022 | |
| 2019 | 2023 | const dest_ty = self.typeOfIndex(inst); |
| 2020 | 2024 | const dest_scalar_ty = dest_ty.scalarType(zcu); |
| 2021 | | const dest_llvm_ty = try o.lowerType(pt, dest_ty); |
| 2025 | const dest_llvm_ty = try self.lowerType(dest_ty); |
| 2022 | 2026 | |
| 2023 | 2027 | if (intrinsicsAllowed(operand_scalar_ty, target)) { |
| 2024 | 2028 | // TODO set fast math flag |
| ... | ... | @@ -2052,8 +2056,8 @@ fn airIntFromFloat( |
| 2052 | 2056 | compiler_rt_dest_abbrev, |
| 2053 | 2057 | }); |
| 2054 | 2058 | |
| 2055 | | const operand_llvm_ty = try o.lowerType(pt, operand_ty); |
| 2056 | | const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty); |
| 2059 | const operand_llvm_ty = try self.lowerType(operand_ty); |
| 2060 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty); |
| 2057 | 2061 | var result = try self.wip.call( |
| 2058 | 2062 | .normal, |
| 2059 | 2063 | .ccc, |
| ... | ... | @@ -2078,7 +2082,7 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator. |
| 2078 | 2082 | const o = fg.object; |
| 2079 | 2083 | const pt = fg.pt; |
| 2080 | 2084 | const zcu = pt.zcu; |
| 2081 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 2085 | const llvm_usize = try fg.lowerType(.usize); |
| 2082 | 2086 | switch (ty.ptrSize(zcu)) { |
| 2083 | 2087 | .slice => { |
| 2084 | 2088 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); |
| ... | ... | @@ -2098,20 +2102,20 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator. |
| 2098 | 2102 | } |
| 2099 | 2103 | } |
| 2100 | 2104 | |
| 2101 | | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: u32) !Builder.Value { |
| 2105 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: u32) Allocator.Error!Builder.Value { |
| 2102 | 2106 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2103 | 2107 | const operand = try self.resolveInst(ty_op.operand); |
| 2104 | 2108 | return self.wip.extractValue(operand, &.{index}, ""); |
| 2105 | 2109 | } |
| 2106 | 2110 | |
| 2107 | | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: u1) !Builder.Value { |
| 2111 | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: u1) Allocator.Error!Builder.Value { |
| 2108 | 2112 | const zcu = self.pt.zcu; |
| 2109 | 2113 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2110 | 2114 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 2111 | 2115 | return self.ptraddConst(slice_ptr, index * Type.usize.abiSize(zcu)); |
| 2112 | 2116 | } |
| 2113 | 2117 | |
| 2114 | | fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2118 | fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2115 | 2119 | const pt = self.pt; |
| 2116 | 2120 | const zcu = pt.zcu; |
| 2117 | 2121 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -2133,7 +2137,7 @@ fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2133 | 2137 | } |
| 2134 | 2138 | } |
| 2135 | 2139 | |
| 2136 | | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2140 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2137 | 2141 | const pt = self.pt; |
| 2138 | 2142 | const zcu = pt.zcu; |
| 2139 | 2143 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | ... | @@ -2146,7 +2150,7 @@ fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2146 | 2150 | return self.ptraddScaled(base_ptr, index, slice_ty.childType(zcu).abiSize(zcu)); |
| 2147 | 2151 | } |
| 2148 | 2152 | |
| 2149 | | fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2153 | fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2150 | 2154 | const pt = self.pt; |
| 2151 | 2155 | const zcu = pt.zcu; |
| 2152 | 2156 | |
| ... | ... | @@ -2169,7 +2173,7 @@ fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2169 | 2173 | return self.wip.extractElement(array_llvm_val, rhs, ""); |
| 2170 | 2174 | } |
| 2171 | 2175 | |
| 2172 | | fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2176 | fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2173 | 2177 | const pt = self.pt; |
| 2174 | 2178 | const zcu = pt.zcu; |
| 2175 | 2179 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -2189,7 +2193,7 @@ fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2189 | 2193 | return self.load(ptr, ptr_ty); |
| 2190 | 2194 | } |
| 2191 | 2195 | |
| 2192 | | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2196 | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2193 | 2197 | const pt = self.pt; |
| 2194 | 2198 | const zcu = pt.zcu; |
| 2195 | 2199 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | ... | @@ -2207,7 +2211,7 @@ fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2207 | 2211 | return self.ptraddScaled(base_ptr, rhs, elem_ty.abiSize(zcu)); |
| 2208 | 2212 | } |
| 2209 | 2213 | |
| 2210 | | fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2214 | fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2211 | 2215 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2212 | 2216 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 2213 | 2217 | const struct_ptr = try self.resolveInst(struct_field.struct_operand); |
| ... | ... | @@ -2219,14 +2223,14 @@ fn airStructFieldPtrIndex( |
| 2219 | 2223 | self: *FuncGen, |
| 2220 | 2224 | inst: Air.Inst.Index, |
| 2221 | 2225 | field_index: u32, |
| 2222 | | ) !Builder.Value { |
| 2226 | ) Allocator.Error!Builder.Value { |
| 2223 | 2227 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2224 | 2228 | const struct_ptr = try self.resolveInst(ty_op.operand); |
| 2225 | 2229 | const struct_ptr_ty = self.typeOf(ty_op.operand); |
| 2226 | 2230 | return self.fieldPtr(struct_ptr, struct_ptr_ty, field_index); |
| 2227 | 2231 | } |
| 2228 | 2232 | |
| 2229 | | fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2233 | fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2230 | 2234 | const o = self.object; |
| 2231 | 2235 | const pt = self.pt; |
| 2232 | 2236 | const zcu = pt.zcu; |
| ... | ... | @@ -2267,7 +2271,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2267 | 2271 | }, |
| 2268 | 2272 | .float => { |
| 2269 | 2273 | // bitcast int->float |
| 2270 | | return self.wip.cast(.bitcast, field_int_val, try o.lowerType(pt, field_ty), ""); |
| 2274 | return self.wip.cast(.bitcast, field_int_val, try self.lowerType(field_ty), ""); |
| 2271 | 2275 | }, |
| 2272 | 2276 | } |
| 2273 | 2277 | } |
| ... | ... | @@ -2292,7 +2296,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2292 | 2296 | } |
| 2293 | 2297 | } |
| 2294 | 2298 | |
| 2295 | | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2299 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2296 | 2300 | const o = self.object; |
| 2297 | 2301 | const pt = self.pt; |
| 2298 | 2302 | const zcu = pt.zcu; |
| ... | ... | @@ -2305,8 +2309,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2305 | 2309 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); |
| 2306 | 2310 | if (field_offset == 0) return field_ptr; |
| 2307 | 2311 | |
| 2308 | | const res_ty = try o.lowerType(pt, ty_pl.ty.toType()); |
| 2309 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 2312 | const res_ty = try self.lowerType(ty_pl.ty.toType()); |
| 2313 | const llvm_usize = try self.lowerType(Type.usize); |
| 2310 | 2314 | |
| 2311 | 2315 | const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, ""); |
| 2312 | 2316 | const base_ptr_int = try self.wip.bin( |
| ... | ... | @@ -2318,19 +2322,19 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2318 | 2322 | return self.wip.cast(.inttoptr, base_ptr_int, res_ty, ""); |
| 2319 | 2323 | } |
| 2320 | 2324 | |
| 2321 | | fn airNot(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2325 | fn airNot(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2322 | 2326 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2323 | 2327 | const operand = try self.resolveInst(ty_op.operand); |
| 2324 | 2328 | |
| 2325 | 2329 | return self.wip.not(operand, ""); |
| 2326 | 2330 | } |
| 2327 | 2331 | |
| 2328 | | fn airUnreach(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 2332 | fn airUnreach(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 2329 | 2333 | _ = inst; |
| 2330 | 2334 | _ = try self.wip.@"unreachable"(); |
| 2331 | 2335 | } |
| 2332 | 2336 | |
| 2333 | | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2337 | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2334 | 2338 | const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 2335 | 2339 | self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1); |
| 2336 | 2340 | self.prev_dbg_column = @intCast(dbg_stmt.column + 1); |
| ... | ... | @@ -2345,19 +2349,13 @@ fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2345 | 2349 | return .none; |
| 2346 | 2350 | } |
| 2347 | 2351 | |
| 2348 | | fn airDbgEmptyStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2352 | fn airDbgEmptyStmt(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2349 | 2353 | _ = self; |
| 2350 | 2354 | _ = inst; |
| 2351 | 2355 | return .none; |
| 2352 | 2356 | } |
| 2353 | 2357 | |
| 2354 | | fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2355 | | const block = self.air.unwrapDbgBlock(inst); |
| 2356 | | self.arg_inline_index = 0; |
| 2357 | | return self.lowerBlock(inst, block.func, block.body); |
| 2358 | | } |
| 2359 | | |
| 2360 | | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2358 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2361 | 2359 | const o = self.object; |
| 2362 | 2360 | const pt = self.pt; |
| 2363 | 2361 | const zcu = pt.zcu; |
| ... | ... | @@ -2390,7 +2388,7 @@ fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2390 | 2388 | return .none; |
| 2391 | 2389 | } |
| 2392 | 2390 | |
| 2393 | | fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Value { |
| 2391 | fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) Allocator.Error!Builder.Value { |
| 2394 | 2392 | const o = self.object; |
| 2395 | 2393 | const pt = self.pt; |
| 2396 | 2394 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | ... | @@ -2468,7 +2466,7 @@ fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Val |
| 2468 | 2466 | return .none; |
| 2469 | 2467 | } |
| 2470 | 2468 | |
| 2471 | | fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2469 | fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value { |
| 2472 | 2470 | // Eventually, the Zig compiler needs to be reworked to have inline |
| 2473 | 2471 | // assembly go through the same parsing code regardless of backend, and |
| 2474 | 2472 | // have LLVM-flavored inline assembly be *output* from that assembler. |
| ... | ... | @@ -2530,7 +2528,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2530 | 2528 | const output_inst = try self.resolveInst(output.operand); |
| 2531 | 2529 | const output_ty = self.typeOf(output.operand); |
| 2532 | 2530 | assert(output_ty.zigTypeTag(zcu) == .pointer); |
| 2533 | | const elem_llvm_ty = try o.lowerType(pt, output_ty.childType(zcu)); |
| 2531 | const elem_llvm_ty = try self.lowerType(output_ty.childType(zcu)); |
| 2534 | 2532 | |
| 2535 | 2533 | switch (constraint[0]) { |
| 2536 | 2534 | '=' => {}, |
| ... | ... | @@ -2568,7 +2566,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2568 | 2566 | llvm_ret_indirect[output.index] = false; |
| 2569 | 2567 | |
| 2570 | 2568 | const ret_ty = self.typeOfIndex(inst); |
| 2571 | | llvm_ret_types[llvm_ret_i] = try o.lowerType(pt, ret_ty); |
| 2569 | llvm_ret_types[llvm_ret_i] = try self.lowerType(ret_ty); |
| 2572 | 2570 | llvm_ret_i += 1; |
| 2573 | 2571 | } |
| 2574 | 2572 | |
| ... | ... | @@ -2607,7 +2605,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2607 | 2605 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 2608 | 2606 | } else { |
| 2609 | 2607 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); |
| 2610 | | const arg_llvm_ty = try o.lowerType(pt, arg_ty); |
| 2608 | const arg_llvm_ty = try self.lowerType(arg_ty); |
| 2611 | 2609 | const load_inst = |
| 2612 | 2610 | try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); |
| 2613 | 2611 | llvm_param_values[llvm_param_i] = load_inst; |
| ... | ... | @@ -2648,7 +2646,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2648 | 2646 | llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: { |
| 2649 | 2647 | if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu)); |
| 2650 | 2648 | |
| 2651 | | break :blk try o.lowerType(pt, if (is_by_ref) arg_ty else arg_ty.childType(zcu)); |
| 2649 | break :blk try self.lowerType(if (is_by_ref) arg_ty else arg_ty.childType(zcu)); |
| 2652 | 2650 | } else .none; |
| 2653 | 2651 | |
| 2654 | 2652 | llvm_param_i += 1; |
| ... | ... | @@ -2662,7 +2660,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2662 | 2660 | if (constraint[0] != '+') continue; |
| 2663 | 2661 | |
| 2664 | 2662 | const rw_ty = self.typeOf(output.operand); |
| 2665 | | const llvm_elem_ty = try o.lowerType(pt, rw_ty.childType(zcu)); |
| 2663 | const llvm_elem_ty = try self.lowerType(rw_ty.childType(zcu)); |
| 2666 | 2664 | if (llvm_ret_indirect[output.index]) { |
| 2667 | 2665 | llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index]; |
| 2668 | 2666 | llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip); |
| ... | ... | @@ -2855,7 +2853,7 @@ fn airIsNonNull( |
| 2855 | 2853 | inst: Air.Inst.Index, |
| 2856 | 2854 | operand_is_ptr: bool, |
| 2857 | 2855 | cond: Builder.IntegerCondition, |
| 2858 | | ) !Builder.Value { |
| 2856 | ) Allocator.Error!Builder.Value { |
| 2859 | 2857 | const o = self.object; |
| 2860 | 2858 | const pt = self.pt; |
| 2861 | 2859 | const zcu = pt.zcu; |
| ... | ... | @@ -2863,7 +2861,7 @@ fn airIsNonNull( |
| 2863 | 2861 | const operand = try self.resolveInst(un_op); |
| 2864 | 2862 | const operand_ty = self.typeOf(un_op); |
| 2865 | 2863 | const optional_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 2866 | | const optional_llvm_ty = try o.lowerType(pt, optional_ty); |
| 2864 | const optional_llvm_ty = try self.lowerType(optional_ty); |
| 2867 | 2865 | const payload_ty = optional_ty.optionalChild(zcu); |
| 2868 | 2866 | |
| 2869 | 2867 | const access_kind: Builder.MemoryAccessKind = |
| ... | ... | @@ -2905,7 +2903,7 @@ fn airIsErr( |
| 2905 | 2903 | inst: Air.Inst.Index, |
| 2906 | 2904 | cond: Builder.IntegerCondition, |
| 2907 | 2905 | operand_is_ptr: bool, |
| 2908 | | ) !Builder.Value { |
| 2906 | ) Allocator.Error!Builder.Value { |
| 2909 | 2907 | const o = self.object; |
| 2910 | 2908 | const pt = self.pt; |
| 2911 | 2909 | const zcu = pt.zcu; |
| ... | ... | @@ -2914,7 +2912,7 @@ fn airIsErr( |
| 2914 | 2912 | const operand_ty = self.typeOf(un_op); |
| 2915 | 2913 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 2916 | 2914 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 2917 | | const error_type = try o.errorIntType(pt); |
| 2915 | const error_type = try o.errorIntType(); |
| 2918 | 2916 | const zero = try o.builder.intValue(error_type, 0); |
| 2919 | 2917 | |
| 2920 | 2918 | const access_kind: Builder.MemoryAccessKind = |
| ... | ... | @@ -2933,7 +2931,7 @@ fn airIsErr( |
| 2933 | 2931 | |
| 2934 | 2932 | if (!payload_ty.hasRuntimeBits(zcu)) { |
| 2935 | 2933 | const loaded = if (operand_is_ptr) |
| 2936 | | try self.wip.load(access_kind, try o.lowerType(pt, err_union_ty), operand, operand_ty.ptrAlignment(zcu).toLlvm(), "") |
| 2934 | try self.wip.load(access_kind, try self.lowerType(err_union_ty), operand, operand_ty.ptrAlignment(zcu).toLlvm(), "") |
| 2937 | 2935 | else |
| 2938 | 2936 | operand; |
| 2939 | 2937 | return self.wip.icmp(cond, loaded, zero, ""); |
| ... | ... | @@ -2957,7 +2955,7 @@ fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!B |
| 2957 | 2955 | return operand; |
| 2958 | 2956 | } |
| 2959 | 2957 | |
| 2960 | | fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2958 | fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 2961 | 2959 | comptime assert(optional_layout_version == 3); |
| 2962 | 2960 | |
| 2963 | 2961 | const o = self.object; |
| ... | ... | @@ -3002,7 +3000,7 @@ fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value |
| 3002 | 3000 | return operand; // payload is at offset 0 |
| 3003 | 3001 | } |
| 3004 | 3002 | |
| 3005 | | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3003 | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3006 | 3004 | const pt = self.pt; |
| 3007 | 3005 | const zcu = pt.zcu; |
| 3008 | 3006 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| ... | ... | @@ -3019,8 +3017,7 @@ fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3019 | 3017 | return self.optPayloadHandle(operand, optional_ty, false); |
| 3020 | 3018 | } |
| 3021 | 3019 | |
| 3022 | | fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool) !Builder.Value { |
| 3023 | | const o = self.object; |
| 3020 | fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool) Allocator.Error!Builder.Value { |
| 3024 | 3021 | const pt = self.pt; |
| 3025 | 3022 | const zcu = pt.zcu; |
| 3026 | 3023 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| ... | ... | @@ -3042,7 +3039,7 @@ fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool |
| 3042 | 3039 | if (isByRef(payload_ty, zcu)) { |
| 3043 | 3040 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); |
| 3044 | 3041 | } else { |
| 3045 | | const payload_llvm_ty = try o.lowerType(pt, payload_ty); |
| 3042 | const payload_llvm_ty = try self.lowerType(payload_ty); |
| 3046 | 3043 | return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, ""); |
| 3047 | 3044 | } |
| 3048 | 3045 | } |
| ... | ... | @@ -3051,14 +3048,14 @@ fn airErrUnionErr( |
| 3051 | 3048 | self: *FuncGen, |
| 3052 | 3049 | inst: Air.Inst.Index, |
| 3053 | 3050 | operand_is_ptr: bool, |
| 3054 | | ) !Builder.Value { |
| 3051 | ) Allocator.Error!Builder.Value { |
| 3055 | 3052 | const o = self.object; |
| 3056 | 3053 | const pt = self.pt; |
| 3057 | 3054 | const zcu = pt.zcu; |
| 3058 | 3055 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3059 | 3056 | const operand = try self.resolveInst(ty_op.operand); |
| 3060 | 3057 | const operand_ty = self.typeOf(ty_op.operand); |
| 3061 | | const error_type = try o.errorIntType(pt); |
| 3058 | const error_type = try o.errorIntType(); |
| 3062 | 3059 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 3063 | 3060 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 3064 | 3061 | if (operand_is_ptr) { |
| ... | ... | @@ -3094,7 +3091,7 @@ fn airErrUnionErr( |
| 3094 | 3091 | return self.wip.load(access_kind, error_type, err_field_ptr, err_align.toLlvm(), ""); |
| 3095 | 3092 | } |
| 3096 | 3093 | |
| 3097 | | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3094 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3098 | 3095 | const o = self.object; |
| 3099 | 3096 | const pt = self.pt; |
| 3100 | 3097 | const zcu = pt.zcu; |
| ... | ... | @@ -3105,7 +3102,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value |
| 3105 | 3102 | const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu); |
| 3106 | 3103 | |
| 3107 | 3104 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 3108 | | const non_error_val = try o.builder.intValue(try o.errorIntType(pt), 0); |
| 3105 | const non_error_val = try o.builder.intValue(try o.errorIntType(), 0); |
| 3109 | 3106 | |
| 3110 | 3107 | const access_kind: Builder.MemoryAccessKind = |
| 3111 | 3108 | if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| ... | ... | @@ -3124,18 +3121,18 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value |
| 3124 | 3121 | return self.ptraddConst(operand, codegen.errUnionPayloadOffset(payload_ty, zcu)); |
| 3125 | 3122 | } |
| 3126 | 3123 | |
| 3127 | | fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !Builder.Value { |
| 3124 | fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3128 | 3125 | assert(self.err_ret_trace != .none); |
| 3129 | 3126 | return self.err_ret_trace; |
| 3130 | 3127 | } |
| 3131 | 3128 | |
| 3132 | | fn airSetErrReturnTrace(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3129 | fn airSetErrReturnTrace(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3133 | 3130 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 3134 | 3131 | self.err_ret_trace = try self.resolveInst(un_op); |
| 3135 | 3132 | return .none; |
| 3136 | 3133 | } |
| 3137 | 3134 | |
| 3138 | | fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3135 | fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3139 | 3136 | const pt = self.pt; |
| 3140 | 3137 | const zcu = pt.zcu; |
| 3141 | 3138 | |
| ... | ... | @@ -3184,7 +3181,7 @@ fn isNextRet( |
| 3184 | 3181 | return false; |
| 3185 | 3182 | } |
| 3186 | 3183 | |
| 3187 | | fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 3184 | fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3188 | 3185 | const o = self.object; |
| 3189 | 3186 | const pt = self.pt; |
| 3190 | 3187 | const zcu = pt.zcu; |
| ... | ... | @@ -3198,7 +3195,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V |
| 3198 | 3195 | const optional_ty = self.typeOfIndex(inst); |
| 3199 | 3196 | if (optional_ty.optionalReprIsPayload(zcu)) return operand; |
| 3200 | 3197 | assert(isByRef(optional_ty, zcu)); // optionals with runtime bits are by-ref unless `optionalReprIsPayload` |
| 3201 | | const llvm_optional_ty = try o.lowerType(pt, optional_ty); |
| 3198 | const llvm_optional_ty = try self.lowerType(optional_ty); |
| 3202 | 3199 | const optional_ptr = if (self.isNextRet(body_tail)) |
| 3203 | 3200 | self.ret_ptr |
| 3204 | 3201 | else brk: { |
| ... | ... | @@ -3216,7 +3213,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V |
| 3216 | 3213 | return optional_ptr; |
| 3217 | 3214 | } |
| 3218 | 3215 | |
| 3219 | | fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 3216 | fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3220 | 3217 | const o = self.object; |
| 3221 | 3218 | const pt = self.pt; |
| 3222 | 3219 | const zcu = pt.zcu; |
| ... | ... | @@ -3227,8 +3224,8 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu |
| 3227 | 3224 | const payload_ty = self.typeOf(ty_op.operand); |
| 3228 | 3225 | assert(payload_ty.hasRuntimeBits(zcu)); |
| 3229 | 3226 | assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref |
| 3230 | | const ok_err_code = try o.builder.intValue(try o.errorIntType(pt), 0); |
| 3231 | | const err_un_llvm_ty = try o.lowerType(pt, err_un_ty); |
| 3227 | const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0); |
| 3228 | const err_un_llvm_ty = try self.lowerType(err_un_ty); |
| 3232 | 3229 | |
| 3233 | 3230 | const result_ptr = if (self.isNextRet(body_tail)) |
| 3234 | 3231 | self.ret_ptr |
| ... | ... | @@ -3247,8 +3244,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu |
| 3247 | 3244 | return result_ptr; |
| 3248 | 3245 | } |
| 3249 | 3246 | |
| 3250 | | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 3251 | | const o = self.object; |
| 3247 | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3252 | 3248 | const pt = self.pt; |
| 3253 | 3249 | const zcu = pt.zcu; |
| 3254 | 3250 | const inst = body_tail[0]; |
| ... | ... | @@ -3258,7 +3254,7 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde |
| 3258 | 3254 | const operand = try self.resolveInst(ty_op.operand); |
| 3259 | 3255 | if (!payload_ty.hasRuntimeBits(zcu)) return operand; |
| 3260 | 3256 | assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref |
| 3261 | | const err_un_llvm_ty = try o.lowerType(pt, err_un_ty); |
| 3257 | const err_un_llvm_ty = try self.lowerType(err_un_ty); |
| 3262 | 3258 | |
| 3263 | 3259 | const result_ptr = if (self.isNextRet(body_tail)) |
| 3264 | 3260 | self.ret_ptr |
| ... | ... | @@ -3279,29 +3275,27 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde |
| 3279 | 3275 | return result_ptr; |
| 3280 | 3276 | } |
| 3281 | 3277 | |
| 3282 | | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3278 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3283 | 3279 | const o = self.object; |
| 3284 | | const pt = self.pt; |
| 3285 | 3280 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 3286 | 3281 | const index = pl_op.payload; |
| 3287 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 3282 | const llvm_usize = try self.lowerType(Type.usize); |
| 3288 | 3283 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{ |
| 3289 | 3284 | try o.builder.intValue(.i32, index), |
| 3290 | 3285 | }, ""); |
| 3291 | 3286 | } |
| 3292 | 3287 | |
| 3293 | | fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3288 | fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3294 | 3289 | const o = self.object; |
| 3295 | | const pt = self.pt; |
| 3296 | 3290 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 3297 | 3291 | const index = pl_op.payload; |
| 3298 | | const llvm_isize = try o.lowerType(pt, Type.isize); |
| 3292 | const llvm_isize = try self.lowerType(Type.isize); |
| 3299 | 3293 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{ |
| 3300 | 3294 | try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand), |
| 3301 | 3295 | }, ""); |
| 3302 | 3296 | } |
| 3303 | 3297 | |
| 3304 | | fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3298 | fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3305 | 3299 | const o = fg.object; |
| 3306 | 3300 | const pt = fg.pt; |
| 3307 | 3301 | const ty_nav = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav; |
| ... | ... | @@ -3309,8 +3303,7 @@ fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3309 | 3303 | return llvm_ptr_const.toValue(); |
| 3310 | 3304 | } |
| 3311 | 3305 | |
| 3312 | | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3313 | | const o = self.object; |
| 3306 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3314 | 3307 | const pt = self.pt; |
| 3315 | 3308 | const zcu = pt.zcu; |
| 3316 | 3309 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -3324,14 +3317,13 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3324 | 3317 | .normal, |
| 3325 | 3318 | .none, |
| 3326 | 3319 | if (scalar_ty.isSignedInt(zcu)) .smin else .umin, |
| 3327 | | &.{try o.lowerType(pt, inst_ty)}, |
| 3320 | &.{try self.lowerType(inst_ty)}, |
| 3328 | 3321 | &.{ lhs, rhs }, |
| 3329 | 3322 | "", |
| 3330 | 3323 | ); |
| 3331 | 3324 | } |
| 3332 | 3325 | |
| 3333 | | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3334 | | const o = self.object; |
| 3326 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3335 | 3327 | const pt = self.pt; |
| 3336 | 3328 | const zcu = pt.zcu; |
| 3337 | 3329 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -3345,24 +3337,22 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3345 | 3337 | .normal, |
| 3346 | 3338 | .none, |
| 3347 | 3339 | if (scalar_ty.isSignedInt(zcu)) .smax else .umax, |
| 3348 | | &.{try o.lowerType(pt, inst_ty)}, |
| 3340 | &.{try self.lowerType(inst_ty)}, |
| 3349 | 3341 | &.{ lhs, rhs }, |
| 3350 | 3342 | "", |
| 3351 | 3343 | ); |
| 3352 | 3344 | } |
| 3353 | 3345 | |
| 3354 | | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3355 | | const o = self.object; |
| 3356 | | const pt = self.pt; |
| 3346 | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3357 | 3347 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3358 | 3348 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3359 | 3349 | const ptr = try self.resolveInst(bin_op.lhs); |
| 3360 | 3350 | const len = try self.resolveInst(bin_op.rhs); |
| 3361 | 3351 | const inst_ty = self.typeOfIndex(inst); |
| 3362 | | return self.wip.buildAggregate(try o.lowerType(pt, inst_ty), &.{ ptr, len }, ""); |
| 3352 | return self.wip.buildAggregate(try self.lowerType(inst_ty), &.{ ptr, len }, ""); |
| 3363 | 3353 | } |
| 3364 | 3354 | |
| 3365 | | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3355 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3366 | 3356 | const zcu = self.pt.zcu; |
| 3367 | 3357 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3368 | 3358 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3379,7 +3369,7 @@ fn airSafeArithmetic( |
| 3379 | 3369 | inst: Air.Inst.Index, |
| 3380 | 3370 | signed_intrinsic: Builder.Intrinsic, |
| 3381 | 3371 | unsigned_intrinsic: Builder.Intrinsic, |
| 3382 | | ) !Builder.Value { |
| 3372 | ) Allocator.Error!Builder.Value { |
| 3383 | 3373 | const o = fg.object; |
| 3384 | 3374 | const pt = fg.pt; |
| 3385 | 3375 | const zcu = pt.zcu; |
| ... | ... | @@ -3391,7 +3381,7 @@ fn airSafeArithmetic( |
| 3391 | 3381 | const scalar_ty = inst_ty.scalarType(zcu); |
| 3392 | 3382 | |
| 3393 | 3383 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; |
| 3394 | | const llvm_inst_ty = try o.lowerType(pt, inst_ty); |
| 3384 | const llvm_inst_ty = try fg.lowerType(inst_ty); |
| 3395 | 3385 | const results = |
| 3396 | 3386 | try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, ""); |
| 3397 | 3387 | |
| ... | ... | @@ -3420,7 +3410,7 @@ fn airSafeArithmetic( |
| 3420 | 3410 | return fg.wip.extractValue(results, &.{0}, ""); |
| 3421 | 3411 | } |
| 3422 | 3412 | |
| 3423 | | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3413 | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3424 | 3414 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3425 | 3415 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3426 | 3416 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3428,8 +3418,7 @@ fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3428 | 3418 | return self.wip.bin(.add, lhs, rhs, ""); |
| 3429 | 3419 | } |
| 3430 | 3420 | |
| 3431 | | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3432 | | const o = self.object; |
| 3421 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3433 | 3422 | const pt = self.pt; |
| 3434 | 3423 | const zcu = pt.zcu; |
| 3435 | 3424 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -3442,13 +3431,13 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3442 | 3431 | .normal, |
| 3443 | 3432 | .none, |
| 3444 | 3433 | if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat", |
| 3445 | | &.{try o.lowerType(pt, inst_ty)}, |
| 3434 | &.{try self.lowerType(inst_ty)}, |
| 3446 | 3435 | &.{ lhs, rhs }, |
| 3447 | 3436 | "", |
| 3448 | 3437 | ); |
| 3449 | 3438 | } |
| 3450 | 3439 | |
| 3451 | | fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3440 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3452 | 3441 | const zcu = self.pt.zcu; |
| 3453 | 3442 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3454 | 3443 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3460,7 +3449,7 @@ fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3460 | 3449 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"sub nsw" else .@"sub nuw", lhs, rhs, ""); |
| 3461 | 3450 | } |
| 3462 | 3451 | |
| 3463 | | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3452 | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3464 | 3453 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3465 | 3454 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3466 | 3455 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3468,8 +3457,7 @@ fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3468 | 3457 | return self.wip.bin(.sub, lhs, rhs, ""); |
| 3469 | 3458 | } |
| 3470 | 3459 | |
| 3471 | | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3472 | | const o = self.object; |
| 3460 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3473 | 3461 | const pt = self.pt; |
| 3474 | 3462 | const zcu = pt.zcu; |
| 3475 | 3463 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -3482,13 +3470,13 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3482 | 3470 | .normal, |
| 3483 | 3471 | .none, |
| 3484 | 3472 | if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat", |
| 3485 | | &.{try o.lowerType(pt, inst_ty)}, |
| 3473 | &.{try self.lowerType(inst_ty)}, |
| 3486 | 3474 | &.{ lhs, rhs }, |
| 3487 | 3475 | "", |
| 3488 | 3476 | ); |
| 3489 | 3477 | } |
| 3490 | 3478 | |
| 3491 | | fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3479 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3492 | 3480 | const zcu = self.pt.zcu; |
| 3493 | 3481 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3494 | 3482 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3500,7 +3488,7 @@ fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3500 | 3488 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"mul nsw" else .@"mul nuw", lhs, rhs, ""); |
| 3501 | 3489 | } |
| 3502 | 3490 | |
| 3503 | | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3491 | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3504 | 3492 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3505 | 3493 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3506 | 3494 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3508,8 +3496,7 @@ fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3508 | 3496 | return self.wip.bin(.mul, lhs, rhs, ""); |
| 3509 | 3497 | } |
| 3510 | 3498 | |
| 3511 | | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3512 | | const o = self.object; |
| 3499 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3513 | 3500 | const pt = self.pt; |
| 3514 | 3501 | const zcu = pt.zcu; |
| 3515 | 3502 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -3522,13 +3509,13 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3522 | 3509 | .normal, |
| 3523 | 3510 | .none, |
| 3524 | 3511 | if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat", |
| 3525 | | &.{try o.lowerType(pt, inst_ty)}, |
| 3512 | &.{try self.lowerType(inst_ty)}, |
| 3526 | 3513 | &.{ lhs, rhs, .@"0" }, |
| 3527 | 3514 | "", |
| 3528 | 3515 | ); |
| 3529 | 3516 | } |
| 3530 | 3517 | |
| 3531 | | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3518 | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3532 | 3519 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3533 | 3520 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3534 | 3521 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3537,7 +3524,7 @@ fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3537 | 3524 | return self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs }); |
| 3538 | 3525 | } |
| 3539 | 3526 | |
| 3540 | | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3527 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3541 | 3528 | const zcu = self.pt.zcu; |
| 3542 | 3529 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3543 | 3530 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3552,7 +3539,7 @@ fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3552 | 3539 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .sdiv else .udiv, lhs, rhs, ""); |
| 3553 | 3540 | } |
| 3554 | 3541 | |
| 3555 | | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3542 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3556 | 3543 | const o = self.object; |
| 3557 | 3544 | const pt = self.pt; |
| 3558 | 3545 | const zcu = pt.zcu; |
| ... | ... | @@ -3567,7 +3554,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3567 | 3554 | return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result}); |
| 3568 | 3555 | } |
| 3569 | 3556 | if (scalar_ty.isSignedInt(zcu)) { |
| 3570 | | const inst_llvm_ty = try o.lowerType(pt, inst_ty); |
| 3557 | const inst_llvm_ty = try self.lowerType(inst_ty); |
| 3571 | 3558 | |
| 3572 | 3559 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; |
| 3573 | 3560 | var stack align(@max( |
| ... | ... | @@ -3603,7 +3590,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3603 | 3590 | return self.wip.bin(.udiv, lhs, rhs, ""); |
| 3604 | 3591 | } |
| 3605 | 3592 | |
| 3606 | | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3593 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3607 | 3594 | const zcu = self.pt.zcu; |
| 3608 | 3595 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3609 | 3596 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3620,7 +3607,7 @@ fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3620 | 3607 | ); |
| 3621 | 3608 | } |
| 3622 | 3609 | |
| 3623 | | fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3610 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3624 | 3611 | const zcu = self.pt.zcu; |
| 3625 | 3612 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3626 | 3613 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3636,7 +3623,7 @@ fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3636 | 3623 | .urem, lhs, rhs, ""); |
| 3637 | 3624 | } |
| 3638 | 3625 | |
| 3639 | | fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 3626 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 3640 | 3627 | const o = self.object; |
| 3641 | 3628 | const pt = self.pt; |
| 3642 | 3629 | const zcu = pt.zcu; |
| ... | ... | @@ -3644,7 +3631,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3644 | 3631 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3645 | 3632 | const rhs = try self.resolveInst(bin_op.rhs); |
| 3646 | 3633 | const inst_ty = self.typeOfIndex(inst); |
| 3647 | | const inst_llvm_ty = try o.lowerType(pt, inst_ty); |
| 3634 | const inst_llvm_ty = try self.lowerType(inst_ty); |
| 3648 | 3635 | const scalar_ty = inst_ty.scalarType(zcu); |
| 3649 | 3636 | |
| 3650 | 3637 | if (scalar_ty.isRuntimeFloat()) { |
| ... | ... | @@ -3690,7 +3677,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3690 | 3677 | return self.wip.bin(.urem, lhs, rhs, ""); |
| 3691 | 3678 | } |
| 3692 | 3679 | |
| 3693 | | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3680 | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3694 | 3681 | const zcu = self.pt.zcu; |
| 3695 | 3682 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3696 | 3683 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | ... | @@ -3705,14 +3692,14 @@ fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3705 | 3692 | return self.ptraddScaled(ptr, index, elem_ty.abiSize(zcu)); |
| 3706 | 3693 | } |
| 3707 | 3694 | |
| 3708 | | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3695 | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3709 | 3696 | const o = self.object; |
| 3710 | 3697 | const pt = self.pt; |
| 3711 | 3698 | const zcu = pt.zcu; |
| 3712 | 3699 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3713 | 3700 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3714 | 3701 | const ptr_or_slice = try self.resolveInst(bin_op.lhs); |
| 3715 | | const llvm_usize_ty = try o.lowerType(pt, .usize); |
| 3702 | const llvm_usize_ty = try self.lowerType(.usize); |
| 3716 | 3703 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3717 | 3704 | const elem_ty = ptr_ty.indexableElem(zcu); |
| 3718 | 3705 | const ptr = switch (ptr_ty.ptrSize(zcu)) { |
| ... | ... | @@ -3722,7 +3709,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3722 | 3709 | const scale_val = try o.builder.intValue(llvm_usize_ty, -@as(i65, elem_ty.abiSize(zcu))); |
| 3723 | 3710 | const positive_index = try self.resolveInst(bin_op.rhs); |
| 3724 | 3711 | const negative_offset = try self.wip.bin(.@"mul nsw", positive_index, scale_val, ""); |
| 3725 | | return self.ptradd(ptr, negative_offset); |
| 3712 | return self.wip.gep(.inbounds, .i8, ptr, &.{negative_offset}, ""); |
| 3726 | 3713 | } |
| 3727 | 3714 | |
| 3728 | 3715 | fn airOverflow( |
| ... | ... | @@ -3730,8 +3717,7 @@ fn airOverflow( |
| 3730 | 3717 | inst: Air.Inst.Index, |
| 3731 | 3718 | signed_intrinsic: Builder.Intrinsic, |
| 3732 | 3719 | unsigned_intrinsic: Builder.Intrinsic, |
| 3733 | | ) !Builder.Value { |
| 3734 | | const o = self.object; |
| 3720 | ) Allocator.Error!Builder.Value { |
| 3735 | 3721 | const pt = self.pt; |
| 3736 | 3722 | const zcu = pt.zcu; |
| 3737 | 3723 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | ... | @@ -3746,8 +3732,8 @@ fn airOverflow( |
| 3746 | 3732 | assert(isByRef(inst_ty, zcu)); // auto structs are by-ref |
| 3747 | 3733 | |
| 3748 | 3734 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; |
| 3749 | | const llvm_inst_ty = try o.lowerType(pt, inst_ty); |
| 3750 | | const llvm_lhs_ty = try o.lowerType(pt, lhs_ty); |
| 3735 | const llvm_inst_ty = try self.lowerType(inst_ty); |
| 3736 | const llvm_lhs_ty = try self.lowerType(lhs_ty); |
| 3751 | 3737 | const results = |
| 3752 | 3738 | try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, ""); |
| 3753 | 3739 | |
| ... | ... | @@ -3778,7 +3764,7 @@ fn buildElementwiseCall( |
| 3778 | 3764 | args_vectors: []const Builder.Value, |
| 3779 | 3765 | result_vector: Builder.Value, |
| 3780 | 3766 | vector_len: usize, |
| 3781 | | ) !Builder.Value { |
| 3767 | ) Allocator.Error!Builder.Value { |
| 3782 | 3768 | const o = self.object; |
| 3783 | 3769 | assert(args_vectors.len <= 3); |
| 3784 | 3770 | |
| ... | ... | @@ -3805,25 +3791,6 @@ fn buildElementwiseCall( |
| 3805 | 3791 | return result; |
| 3806 | 3792 | } |
| 3807 | 3793 | |
| 3808 | | fn getLibcFunction( |
| 3809 | | self: *FuncGen, |
| 3810 | | fn_name: Builder.StrtabString, |
| 3811 | | param_types: []const Builder.Type, |
| 3812 | | return_type: Builder.Type, |
| 3813 | | ) Allocator.Error!Builder.Function.Index { |
| 3814 | | const o = self.object; |
| 3815 | | if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) { |
| 3816 | | .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function, |
| 3817 | | .function => |function| function, |
| 3818 | | .variable, .replaced => unreachable, |
| 3819 | | }; |
| 3820 | | return o.builder.addFunction( |
| 3821 | | try o.builder.fnType(return_type, param_types, .normal), |
| 3822 | | fn_name, |
| 3823 | | toLlvmAddressSpace(.generic, self.pt.zcu.getTarget()), |
| 3824 | | ); |
| 3825 | | } |
| 3826 | | |
| 3827 | 3794 | /// Creates a floating point comparison by lowering to the appropriate |
| 3828 | 3795 | /// hardware instruction or softfloat routine for the target |
| 3829 | 3796 | fn buildFloatCmp( |
| ... | ... | @@ -3832,13 +3799,13 @@ fn buildFloatCmp( |
| 3832 | 3799 | pred: math.CompareOperator, |
| 3833 | 3800 | ty: Type, |
| 3834 | 3801 | params: [2]Builder.Value, |
| 3835 | | ) !Builder.Value { |
| 3802 | ) Allocator.Error!Builder.Value { |
| 3836 | 3803 | const o = self.object; |
| 3837 | 3804 | const pt = self.pt; |
| 3838 | 3805 | const zcu = pt.zcu; |
| 3839 | 3806 | const target = zcu.getTarget(); |
| 3840 | 3807 | const scalar_ty = ty.scalarType(zcu); |
| 3841 | | const scalar_llvm_ty = try o.lowerType(pt, scalar_ty); |
| 3808 | const scalar_llvm_ty = try self.lowerType(scalar_ty); |
| 3842 | 3809 | |
| 3843 | 3810 | if (intrinsicsAllowed(scalar_ty, target)) { |
| 3844 | 3811 | const cond: Builder.FloatCondition = switch (pred) { |
| ... | ... | @@ -3864,7 +3831,7 @@ fn buildFloatCmp( |
| 3864 | 3831 | }; |
| 3865 | 3832 | const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev }); |
| 3866 | 3833 | |
| 3867 | | const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32); |
| 3834 | const libc_fn = try o.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32); |
| 3868 | 3835 | |
| 3869 | 3836 | const int_cond: Builder.IntegerCondition = switch (pred) { |
| 3870 | 3837 | .eq => .eq, |
| ... | ... | @@ -3939,13 +3906,13 @@ fn buildFloatOp( |
| 3939 | 3906 | ty: Type, |
| 3940 | 3907 | comptime params_len: usize, |
| 3941 | 3908 | params: [params_len]Builder.Value, |
| 3942 | | ) !Builder.Value { |
| 3909 | ) Allocator.Error!Builder.Value { |
| 3943 | 3910 | const o = self.object; |
| 3944 | 3911 | const pt = self.pt; |
| 3945 | 3912 | const zcu = pt.zcu; |
| 3946 | 3913 | const target = zcu.getTarget(); |
| 3947 | 3914 | const scalar_ty = ty.scalarType(zcu); |
| 3948 | | const llvm_ty = try o.lowerType(pt, ty); |
| 3915 | const llvm_ty = try self.lowerType(ty); |
| 3949 | 3916 | |
| 3950 | 3917 | if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) { |
| 3951 | 3918 | // Some operations are dedicated LLVM instructions, not available as intrinsics |
| ... | ... | @@ -4048,7 +4015,7 @@ fn buildFloatOp( |
| 4048 | 4015 | }; |
| 4049 | 4016 | |
| 4050 | 4017 | const scalar_llvm_ty = llvm_ty.scalarType(&o.builder); |
| 4051 | | const libc_fn = try self.getLibcFunction( |
| 4018 | const libc_fn = try o.getLibcFunction( |
| 4052 | 4019 | fn_name, |
| 4053 | 4020 | ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len], |
| 4054 | 4021 | scalar_llvm_ty, |
| ... | ... | @@ -4069,7 +4036,7 @@ fn buildFloatOp( |
| 4069 | 4036 | ); |
| 4070 | 4037 | } |
| 4071 | 4038 | |
| 4072 | | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4039 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4073 | 4040 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4074 | 4041 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 4075 | 4042 | |
| ... | ... | @@ -4081,8 +4048,7 @@ fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4081 | 4048 | return self.buildFloatOp(.fma, .normal, ty, 3, .{ mulend1, mulend2, addend }); |
| 4082 | 4049 | } |
| 4083 | 4050 | |
| 4084 | | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4085 | | const o = self.object; |
| 4051 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4086 | 4052 | const pt = self.pt; |
| 4087 | 4053 | const zcu = pt.zcu; |
| 4088 | 4054 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | ... | @@ -4092,15 +4058,19 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4092 | 4058 | const rhs = try self.resolveInst(extra.rhs); |
| 4093 | 4059 | |
| 4094 | 4060 | const lhs_ty = self.typeOf(extra.lhs); |
| 4095 | | if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) |
| 4096 | | return self.todo("implement vector shifts with scalar rhs", .{}); |
| 4061 | if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) { |
| 4062 | // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize` |
| 4063 | // features which we do not use. Therefore this branch is currently impossible. |
| 4064 | unreachable; |
| 4065 | } |
| 4066 | |
| 4097 | 4067 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 4098 | 4068 | |
| 4099 | 4069 | const dest_ty = self.typeOfIndex(inst); |
| 4100 | 4070 | assert(isByRef(dest_ty, zcu)); // auto structs are by-ref |
| 4101 | | const llvm_dest_ty = try o.lowerType(pt, dest_ty); |
| 4071 | const llvm_dest_ty = try self.lowerType(dest_ty); |
| 4102 | 4072 | |
| 4103 | | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), ""); |
| 4073 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), ""); |
| 4104 | 4074 | |
| 4105 | 4075 | const result = try self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 4106 | 4076 | const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) |
| ... | ... | @@ -4128,29 +4098,28 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4128 | 4098 | return alloca_inst; |
| 4129 | 4099 | } |
| 4130 | 4100 | |
| 4131 | | fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4101 | fn airAnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4132 | 4102 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4133 | 4103 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4134 | 4104 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4135 | 4105 | return self.wip.bin(.@"and", lhs, rhs, ""); |
| 4136 | 4106 | } |
| 4137 | 4107 | |
| 4138 | | fn airOr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4108 | fn airOr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4139 | 4109 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4140 | 4110 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4141 | 4111 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4142 | 4112 | return self.wip.bin(.@"or", lhs, rhs, ""); |
| 4143 | 4113 | } |
| 4144 | 4114 | |
| 4145 | | fn airXor(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4115 | fn airXor(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4146 | 4116 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4147 | 4117 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4148 | 4118 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4149 | 4119 | return self.wip.bin(.xor, lhs, rhs, ""); |
| 4150 | 4120 | } |
| 4151 | 4121 | |
| 4152 | | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4153 | | const o = self.object; |
| 4122 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4154 | 4123 | const pt = self.pt; |
| 4155 | 4124 | const zcu = pt.zcu; |
| 4156 | 4125 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -4159,19 +4128,21 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4159 | 4128 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4160 | 4129 | |
| 4161 | 4130 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4162 | | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) |
| 4163 | | return self.todo("implement vector shifts with scalar rhs", .{}); |
| 4131 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { |
| 4132 | // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize` |
| 4133 | // features which we do not use. Therefore this branch is currently impossible. |
| 4134 | unreachable; |
| 4135 | } |
| 4164 | 4136 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 4165 | 4137 | |
| 4166 | | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), ""); |
| 4138 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), ""); |
| 4167 | 4139 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) |
| 4168 | 4140 | .@"shl nsw" |
| 4169 | 4141 | else |
| 4170 | 4142 | .@"shl nuw", lhs, casted_rhs, ""); |
| 4171 | 4143 | } |
| 4172 | 4144 | |
| 4173 | | fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4174 | | const o = self.object; |
| 4145 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4175 | 4146 | const pt = self.pt; |
| 4176 | 4147 | const zcu = pt.zcu; |
| 4177 | 4148 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -4180,14 +4151,16 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4180 | 4151 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4181 | 4152 | |
| 4182 | 4153 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4183 | | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) |
| 4184 | | return self.todo("implement vector shifts with scalar rhs", .{}); |
| 4185 | | |
| 4186 | | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), ""); |
| 4154 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { |
| 4155 | // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize` |
| 4156 | // features which we do not use. Therefore this branch is currently impossible. |
| 4157 | unreachable; |
| 4158 | } |
| 4159 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), ""); |
| 4187 | 4160 | return self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 4188 | 4161 | } |
| 4189 | 4162 | |
| 4190 | | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4163 | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4191 | 4164 | const o = self.object; |
| 4192 | 4165 | const pt = self.pt; |
| 4193 | 4166 | const zcu = pt.zcu; |
| ... | ... | @@ -4198,15 +4171,18 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4198 | 4171 | |
| 4199 | 4172 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4200 | 4173 | const lhs_info = lhs_ty.intInfo(zcu); |
| 4201 | | const llvm_lhs_ty = try o.lowerType(pt, lhs_ty); |
| 4174 | const llvm_lhs_ty = try self.lowerType(lhs_ty); |
| 4202 | 4175 | const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder); |
| 4203 | 4176 | |
| 4204 | 4177 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 4205 | | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) |
| 4206 | | return self.todo("implement vector shifts with scalar rhs", .{}); |
| 4178 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) { |
| 4179 | // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize` |
| 4180 | // features which we do not use. Therefore this branch is currently impossible. |
| 4181 | unreachable; |
| 4182 | } |
| 4207 | 4183 | const rhs_info = rhs_ty.intInfo(zcu); |
| 4208 | 4184 | assert(rhs_info.signedness == .unsigned); |
| 4209 | | const llvm_rhs_ty = try o.lowerType(pt, rhs_ty); |
| 4185 | const llvm_rhs_ty = try self.lowerType(rhs_ty); |
| 4210 | 4186 | const llvm_rhs_scalar_ty = llvm_rhs_ty.scalarType(&o.builder); |
| 4211 | 4187 | |
| 4212 | 4188 | const result = try self.wip.callIntrinsic( |
| ... | ... | @@ -4267,8 +4243,7 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4267 | 4243 | return self.wip.select(.normal, in_range, result, lhs_sat, ""); |
| 4268 | 4244 | } |
| 4269 | 4245 | |
| 4270 | | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 4271 | | const o = self.object; |
| 4246 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error!Builder.Value { |
| 4272 | 4247 | const pt = self.pt; |
| 4273 | 4248 | const zcu = pt.zcu; |
| 4274 | 4249 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -4277,11 +4252,14 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 4277 | 4252 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4278 | 4253 | |
| 4279 | 4254 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4280 | | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) |
| 4281 | | return self.todo("implement vector shifts with scalar rhs", .{}); |
| 4255 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { |
| 4256 | // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize` |
| 4257 | // features which we do not use. Therefore this branch is currently impossible. |
| 4258 | unreachable; |
| 4259 | } |
| 4282 | 4260 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 4283 | 4261 | |
| 4284 | | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), ""); |
| 4262 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), ""); |
| 4285 | 4263 | const is_signed_int = lhs_scalar_ty.isSignedInt(zcu); |
| 4286 | 4264 | |
| 4287 | 4265 | return self.wip.bin(if (is_exact) |
| ... | ... | @@ -4289,7 +4267,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 4289 | 4267 | else if (is_signed_int) .ashr else .lshr, lhs, casted_rhs, ""); |
| 4290 | 4268 | } |
| 4291 | 4269 | |
| 4292 | | fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4270 | fn airAbs(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4293 | 4271 | const o = self.object; |
| 4294 | 4272 | const pt = self.pt; |
| 4295 | 4273 | const zcu = pt.zcu; |
| ... | ... | @@ -4303,7 +4281,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4303 | 4281 | .normal, |
| 4304 | 4282 | .none, |
| 4305 | 4283 | .abs, |
| 4306 | | &.{try o.lowerType(pt, operand_ty)}, |
| 4284 | &.{try self.lowerType(operand_ty)}, |
| 4307 | 4285 | &.{ operand, try o.builder.intValue(.i1, 0) }, |
| 4308 | 4286 | "", |
| 4309 | 4287 | ), |
| ... | ... | @@ -4312,13 +4290,13 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4312 | 4290 | } |
| 4313 | 4291 | } |
| 4314 | 4292 | |
| 4315 | | fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4293 | fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { |
| 4316 | 4294 | const o = fg.object; |
| 4317 | 4295 | const pt = fg.pt; |
| 4318 | 4296 | const zcu = pt.zcu; |
| 4319 | 4297 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4320 | 4298 | const dest_ty = fg.typeOfIndex(inst); |
| 4321 | | const dest_llvm_ty = try o.lowerType(pt, dest_ty); |
| 4299 | const dest_llvm_ty = try fg.lowerType(dest_ty); |
| 4322 | 4300 | const operand = try fg.resolveInst(ty_op.operand); |
| 4323 | 4301 | const operand_ty = fg.typeOf(ty_op.operand); |
| 4324 | 4302 | const operand_info = operand_ty.intInfo(zcu); |
| ... | ... | @@ -4346,8 +4324,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4346 | 4324 | |
| 4347 | 4325 | if (!have_min_check and !have_max_check) break :bounds_check; |
| 4348 | 4326 | |
| 4349 | | const operand_llvm_ty = try o.lowerType(pt, operand_ty); |
| 4350 | | const operand_scalar_llvm_ty = try o.lowerType(pt, operand_scalar); |
| 4327 | const operand_llvm_ty = try fg.lowerType(operand_ty); |
| 4328 | const operand_scalar_llvm_ty = try fg.lowerType(operand_scalar); |
| 4351 | 4329 | |
| 4352 | 4330 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 4353 | 4331 | assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector)); |
| ... | ... | @@ -4401,7 +4379,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4401 | 4379 | }, operand, dest_llvm_ty, ""); |
| 4402 | 4380 | |
| 4403 | 4381 | if (safety and dest_is_enum and !dest_ty.isNonexhaustiveEnum(zcu)) { |
| 4404 | | const llvm_fn = try fg.getIsNamedEnumValueFunction(dest_ty); |
| 4382 | const llvm_fn = try o.getIsNamedEnumValueFunction(pt, dest_ty); |
| 4405 | 4383 | const is_valid_enum_val = try fg.wip.call( |
| 4406 | 4384 | .normal, |
| 4407 | 4385 | .fastcc, |
| ... | ... | @@ -4422,16 +4400,14 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4422 | 4400 | return result; |
| 4423 | 4401 | } |
| 4424 | 4402 | |
| 4425 | | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4426 | | const o = self.object; |
| 4427 | | const pt = self.pt; |
| 4403 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4428 | 4404 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4429 | 4405 | const operand = try self.resolveInst(ty_op.operand); |
| 4430 | | const dest_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst)); |
| 4406 | const dest_llvm_ty = try self.lowerType(self.typeOfIndex(inst)); |
| 4431 | 4407 | return self.wip.cast(.trunc, operand, dest_llvm_ty, ""); |
| 4432 | 4408 | } |
| 4433 | 4409 | |
| 4434 | | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4410 | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4435 | 4411 | const o = self.object; |
| 4436 | 4412 | const pt = self.pt; |
| 4437 | 4413 | const zcu = pt.zcu; |
| ... | ... | @@ -4442,10 +4418,10 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4442 | 4418 | const target = zcu.getTarget(); |
| 4443 | 4419 | |
| 4444 | 4420 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 4445 | | return self.wip.cast(.fptrunc, operand, try o.lowerType(pt, dest_ty), ""); |
| 4421 | return self.wip.cast(.fptrunc, operand, try self.lowerType(dest_ty), ""); |
| 4446 | 4422 | } else { |
| 4447 | | const operand_llvm_ty = try o.lowerType(pt, operand_ty); |
| 4448 | | const dest_llvm_ty = try o.lowerType(pt, dest_ty); |
| 4423 | const operand_llvm_ty = try self.lowerType(operand_ty); |
| 4424 | const dest_llvm_ty = try self.lowerType(dest_ty); |
| 4449 | 4425 | |
| 4450 | 4426 | const dest_bits = dest_ty.floatBits(target); |
| 4451 | 4427 | const src_bits = operand_ty.floatBits(target); |
| ... | ... | @@ -4453,7 +4429,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4453 | 4429 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), |
| 4454 | 4430 | }); |
| 4455 | 4431 | |
| 4456 | | const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); |
| 4432 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); |
| 4457 | 4433 | return self.wip.call( |
| 4458 | 4434 | .normal, |
| 4459 | 4435 | .ccc, |
| ... | ... | @@ -4466,7 +4442,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4466 | 4442 | } |
| 4467 | 4443 | } |
| 4468 | 4444 | |
| 4469 | | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4445 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4470 | 4446 | const o = self.object; |
| 4471 | 4447 | const pt = self.pt; |
| 4472 | 4448 | const zcu = pt.zcu; |
| ... | ... | @@ -4477,10 +4453,10 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4477 | 4453 | const target = zcu.getTarget(); |
| 4478 | 4454 | |
| 4479 | 4455 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { |
| 4480 | | return self.wip.cast(.fpext, operand, try o.lowerType(pt, dest_ty), ""); |
| 4456 | return self.wip.cast(.fpext, operand, try self.lowerType(dest_ty), ""); |
| 4481 | 4457 | } else { |
| 4482 | | const operand_llvm_ty = try o.lowerType(pt, operand_ty); |
| 4483 | | const dest_llvm_ty = try o.lowerType(pt, dest_ty); |
| 4458 | const operand_llvm_ty = try self.lowerType(operand_ty); |
| 4459 | const dest_llvm_ty = try self.lowerType(dest_ty); |
| 4484 | 4460 | |
| 4485 | 4461 | const dest_bits = dest_ty.scalarType(zcu).floatBits(target); |
| 4486 | 4462 | const src_bits = operand_ty.scalarType(zcu).floatBits(target); |
| ... | ... | @@ -4488,7 +4464,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4488 | 4464 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), |
| 4489 | 4465 | }); |
| 4490 | 4466 | |
| 4491 | | const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); |
| 4467 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty); |
| 4492 | 4468 | if (dest_ty.isVector(zcu)) return self.buildElementwiseCall( |
| 4493 | 4469 | libc_fn, |
| 4494 | 4470 | &.{operand}, |
| ... | ... | @@ -4507,7 +4483,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4507 | 4483 | } |
| 4508 | 4484 | } |
| 4509 | 4485 | |
| 4510 | | fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4486 | fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4511 | 4487 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4512 | 4488 | const operand_ty = self.typeOf(ty_op.operand); |
| 4513 | 4489 | const inst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -4515,13 +4491,13 @@ fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4515 | 4491 | return self.bitCast(operand, operand_ty, inst_ty); |
| 4516 | 4492 | } |
| 4517 | 4493 | |
| 4518 | | fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value { |
| 4494 | fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) Allocator.Error!Builder.Value { |
| 4519 | 4495 | const o = self.object; |
| 4520 | 4496 | const pt = self.pt; |
| 4521 | 4497 | const zcu = pt.zcu; |
| 4522 | 4498 | const operand_is_ref = isByRef(operand_ty, zcu); |
| 4523 | 4499 | const result_is_ref = isByRef(inst_ty, zcu); |
| 4524 | | const llvm_dest_ty = try o.lowerType(pt, inst_ty); |
| 4500 | const llvm_dest_ty = try self.lowerType(inst_ty); |
| 4525 | 4501 | |
| 4526 | 4502 | if (operand_is_ref and result_is_ref) { |
| 4527 | 4503 | // They are both pointers, so just return the same opaque pointer :) |
| ... | ... | @@ -4544,11 +4520,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4544 | 4520 | } |
| 4545 | 4521 | |
| 4546 | 4522 | if (operand_ty.zigTypeTag(zcu) == .vector and inst_ty.zigTypeTag(zcu) == .array) { |
| 4547 | | const elem_ty = inst_ty.childType(zcu); |
| 4548 | | assert(elem_ty.toIntern() == operand_scalar_ty.toIntern()); |
| 4549 | | if (!result_is_ref) { |
| 4550 | | return self.todo("implement bitcast vector to non-ref array", .{}); |
| 4551 | | } |
| 4523 | const elem_ty = operand_scalar_ty; |
| 4524 | assert(result_is_ref); // arrays are always by-ref provided they have runtime bits |
| 4552 | 4525 | const alignment = inst_ty.abiAlignment(zcu).toLlvm(); |
| 4553 | 4526 | const array_ptr = try self.buildAlloca(llvm_dest_ty, alignment); |
| 4554 | 4527 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; |
| ... | ... | @@ -4569,9 +4542,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4569 | 4542 | return array_ptr; |
| 4570 | 4543 | } else if (operand_ty.zigTypeTag(zcu) == .array and inst_ty.zigTypeTag(zcu) == .vector) { |
| 4571 | 4544 | const elem_ty = operand_ty.childType(zcu); |
| 4572 | | assert(elem_ty.toIntern() == inst_scalar_ty.toIntern()); |
| 4573 | | const llvm_vector_ty = try o.lowerType(pt, inst_ty); |
| 4574 | | if (!operand_is_ref) return self.todo("implement bitcast non-ref array to vector", .{}); |
| 4545 | assert(operand_is_ref); // arrays are always by-ref provided they have runtime bits |
| 4546 | const llvm_vector_ty = try self.lowerType(inst_ty); |
| 4575 | 4547 | |
| 4576 | 4548 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; |
| 4577 | 4549 | if (bitcast_ok) { |
| ... | ... | @@ -4582,7 +4554,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4582 | 4554 | } else { |
| 4583 | 4555 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 4584 | 4556 | // a simple bitcast will not work, and we fall back to extractelement. |
| 4585 | | const elem_llvm_ty = try o.lowerType(pt, elem_ty); |
| 4557 | const elem_llvm_ty = try self.lowerType(elem_ty); |
| 4586 | 4558 | const elem_size = elem_ty.abiSize(zcu); |
| 4587 | 4559 | const vector_len = operand_ty.arrayLen(zcu); |
| 4588 | 4560 | var vector = try o.builder.poisonValue(llvm_vector_ty); |
| ... | ... | @@ -4624,7 +4596,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4624 | 4596 | return self.wip.cast(.bitcast, operand, llvm_dest_ty, ""); |
| 4625 | 4597 | } |
| 4626 | 4598 | |
| 4627 | | fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4599 | fn airArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4628 | 4600 | const o = self.object; |
| 4629 | 4601 | const pt = self.pt; |
| 4630 | 4602 | const zcu = pt.zcu; |
| ... | ... | @@ -4714,7 +4686,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4714 | 4686 | return arg_val; |
| 4715 | 4687 | } |
| 4716 | 4688 | |
| 4717 | | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4689 | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4718 | 4690 | const o = self.object; |
| 4719 | 4691 | const pt = self.pt; |
| 4720 | 4692 | const zcu = pt.zcu; |
| ... | ... | @@ -4723,12 +4695,12 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4723 | 4695 | if (!pointee_type.hasRuntimeBits(zcu)) |
| 4724 | 4696 | return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue(); |
| 4725 | 4697 | |
| 4726 | | const pointee_llvm_ty = try o.lowerType(pt, pointee_type); |
| 4698 | const pointee_llvm_ty = try self.lowerType(pointee_type); |
| 4727 | 4699 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); |
| 4728 | 4700 | return self.buildAlloca(pointee_llvm_ty, alignment); |
| 4729 | 4701 | } |
| 4730 | 4702 | |
| 4731 | | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4703 | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4732 | 4704 | const o = self.object; |
| 4733 | 4705 | const pt = self.pt; |
| 4734 | 4706 | const zcu = pt.zcu; |
| ... | ... | @@ -4737,7 +4709,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4737 | 4709 | if (!ret_ty.hasRuntimeBits(zcu)) |
| 4738 | 4710 | return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue(); |
| 4739 | 4711 | if (self.ret_ptr != .none) return self.ret_ptr; |
| 4740 | | const ret_llvm_ty = try o.lowerType(pt, ret_ty); |
| 4712 | const ret_llvm_ty = try self.lowerType(ret_ty); |
| 4741 | 4713 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); |
| 4742 | 4714 | return self.buildAlloca(ret_llvm_ty, alignment); |
| 4743 | 4715 | } |
| ... | ... | @@ -4753,7 +4725,7 @@ fn buildAlloca( |
| 4753 | 4725 | return buildAllocaInner(&self.wip, llvm_ty, alignment, target); |
| 4754 | 4726 | } |
| 4755 | 4727 | |
| 4756 | | fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4728 | fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { |
| 4757 | 4729 | const o = self.object; |
| 4758 | 4730 | const pt = self.pt; |
| 4759 | 4731 | const zcu = pt.zcu; |
| ... | ... | @@ -4790,7 +4762,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4790 | 4762 | |
| 4791 | 4763 | self.maybeMarkAllowZeroAccess(ptr_info); |
| 4792 | 4764 | |
| 4793 | | const len = try o.builder.intValue(try o.lowerType(pt, Type.usize), operand_ty.abiSize(zcu)); |
| 4765 | const len = try o.builder.intValue(try self.lowerType(Type.usize), operand_ty.abiSize(zcu)); |
| 4794 | 4766 | _ = try self.wip.callMemSet( |
| 4795 | 4767 | dest_ptr, |
| 4796 | 4768 | ptr_ty.ptrAlignment(zcu).toLlvm(), |
| ... | ... | @@ -4812,7 +4784,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4812 | 4784 | return .none; |
| 4813 | 4785 | } |
| 4814 | 4786 | |
| 4815 | | fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4787 | fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4816 | 4788 | const pt = fg.pt; |
| 4817 | 4789 | const zcu = pt.zcu; |
| 4818 | 4790 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| ... | ... | @@ -4823,7 +4795,7 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4823 | 4795 | return fg.load(ptr, ptr_ty); |
| 4824 | 4796 | } |
| 4825 | 4797 | |
| 4826 | | fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 4798 | fn airTrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void { |
| 4827 | 4799 | _ = inst; |
| 4828 | 4800 | const target = self.pt.zcu.getTarget(); |
| 4829 | 4801 | if ((target.cpu.arch == .mips or target.cpu.arch == .mipsel) and |
| ... | ... | @@ -4847,17 +4819,16 @@ fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 4847 | 4819 | _ = try self.wip.@"unreachable"(); |
| 4848 | 4820 | } |
| 4849 | 4821 | |
| 4850 | | fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4822 | fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4851 | 4823 | _ = inst; |
| 4852 | 4824 | _ = try self.wip.callIntrinsic(.normal, .none, .debugtrap, &.{}, &.{}, ""); |
| 4853 | 4825 | return .none; |
| 4854 | 4826 | } |
| 4855 | 4827 | |
| 4856 | | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4828 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4857 | 4829 | _ = inst; |
| 4858 | 4830 | const o = self.object; |
| 4859 | | const pt = self.pt; |
| 4860 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 4831 | const llvm_usize = try self.lowerType(Type.usize); |
| 4861 | 4832 | if (!target_util.supportsReturnAddress(self.pt.zcu.getTarget(), self.ownerModule().optimize_mode)) { |
| 4862 | 4833 | // https://github.com/ziglang/zig/issues/11946 |
| 4863 | 4834 | return o.builder.intValue(llvm_usize, 0); |
| ... | ... | @@ -4866,19 +4837,17 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4866 | 4837 | return self.wip.cast(.ptrtoint, result, llvm_usize, ""); |
| 4867 | 4838 | } |
| 4868 | 4839 | |
| 4869 | | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4840 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4870 | 4841 | _ = inst; |
| 4871 | | const o = self.object; |
| 4872 | | const pt = self.pt; |
| 4873 | 4842 | const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, ""); |
| 4874 | | return self.wip.cast(.ptrtoint, result, try o.lowerType(pt, Type.usize), ""); |
| 4843 | return self.wip.cast(.ptrtoint, result, try self.lowerType(Type.usize), ""); |
| 4875 | 4844 | } |
| 4876 | 4845 | |
| 4877 | 4846 | fn airCmpxchg( |
| 4878 | 4847 | self: *FuncGen, |
| 4879 | 4848 | inst: Air.Inst.Index, |
| 4880 | 4849 | kind: Builder.Function.Instruction.CmpXchg.Kind, |
| 4881 | | ) !Builder.Value { |
| 4850 | ) Allocator.Error!Builder.Value { |
| 4882 | 4851 | const o = self.object; |
| 4883 | 4852 | const pt = self.pt; |
| 4884 | 4853 | const zcu = pt.zcu; |
| ... | ... | @@ -4889,7 +4858,7 @@ fn airCmpxchg( |
| 4889 | 4858 | var expected_value = try self.resolveInst(extra.expected_value); |
| 4890 | 4859 | var new_value = try self.resolveInst(extra.new_value); |
| 4891 | 4860 | const operand_ty = ptr_ty.childType(zcu); |
| 4892 | | const llvm_operand_ty = try o.lowerType(pt, operand_ty); |
| 4861 | const llvm_operand_ty = try self.lowerType(operand_ty); |
| 4893 | 4862 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false); |
| 4894 | 4863 | if (llvm_abi_ty != .none) { |
| 4895 | 4864 | // operand needs widening and truncating |
| ... | ... | @@ -4932,7 +4901,7 @@ fn airCmpxchg( |
| 4932 | 4901 | const non_null_bit = try self.wip.not(success_bit, ""); |
| 4933 | 4902 | |
| 4934 | 4903 | const payload_align = operand_ty.abiAlignment(zcu).toLlvm(); |
| 4935 | | const alloca_inst = try self.buildAlloca(try o.lowerType(pt, optional_ty), payload_align); |
| 4904 | const alloca_inst = try self.buildAlloca(try self.lowerType(optional_ty), payload_align); |
| 4936 | 4905 | |
| 4937 | 4906 | // Payload is always the first field at offset 0, so address is `alloca_inst` |
| 4938 | 4907 | _ = try self.wip.store(.normal, payload, alloca_inst, payload_align); |
| ... | ... | @@ -4944,7 +4913,7 @@ fn airCmpxchg( |
| 4944 | 4913 | return alloca_inst; |
| 4945 | 4914 | } |
| 4946 | 4915 | |
| 4947 | | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4916 | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4948 | 4917 | const o = self.object; |
| 4949 | 4918 | const pt = self.pt; |
| 4950 | 4919 | const zcu = pt.zcu; |
| ... | ... | @@ -4959,7 +4928,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4959 | 4928 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); |
| 4960 | 4929 | const ordering = toLlvmAtomicOrdering(extra.ordering()); |
| 4961 | 4930 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg); |
| 4962 | | const llvm_operand_ty = try o.lowerType(pt, operand_ty); |
| 4931 | const llvm_operand_ty = try self.lowerType(operand_ty); |
| 4963 | 4932 | |
| 4964 | 4933 | const access_kind: Builder.MemoryAccessKind = |
| 4965 | 4934 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| ... | ... | @@ -5002,7 +4971,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5002 | 4971 | access_kind, |
| 5003 | 4972 | op, |
| 5004 | 4973 | ptr, |
| 5005 | | try self.wip.cast(.ptrtoint, operand, try o.lowerType(pt, Type.usize), ""), |
| 4974 | try self.wip.cast(.ptrtoint, operand, try self.lowerType(Type.usize), ""), |
| 5006 | 4975 | self.sync_scope, |
| 5007 | 4976 | ordering, |
| 5008 | 4977 | ptr_alignment, |
| ... | ... | @@ -5010,8 +4979,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5010 | 4979 | ), llvm_operand_ty, ""); |
| 5011 | 4980 | } |
| 5012 | 4981 | |
| 5013 | | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5014 | | const o = self.object; |
| 4982 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5015 | 4983 | const pt = self.pt; |
| 5016 | 4984 | const zcu = pt.zcu; |
| 5017 | 4985 | const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| ... | ... | @@ -5028,7 +4996,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5028 | 4996 | Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm(); |
| 5029 | 4997 | const access_kind: Builder.MemoryAccessKind = |
| 5030 | 4998 | if (info.flags.is_volatile) .@"volatile" else .normal; |
| 5031 | | const elem_llvm_ty = try o.lowerType(pt, elem_ty); |
| 4999 | const elem_llvm_ty = try self.lowerType(elem_ty); |
| 5032 | 5000 | |
| 5033 | 5001 | self.maybeMarkAllowZeroAccess(info); |
| 5034 | 5002 | |
| ... | ... | @@ -5060,7 +5028,7 @@ fn airAtomicStore( |
| 5060 | 5028 | self: *FuncGen, |
| 5061 | 5029 | inst: Air.Inst.Index, |
| 5062 | 5030 | ordering: Builder.AtomicOrdering, |
| 5063 | | ) !Builder.Value { |
| 5031 | ) Allocator.Error!Builder.Value { |
| 5064 | 5032 | const pt = self.pt; |
| 5065 | 5033 | const zcu = pt.zcu; |
| 5066 | 5034 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -5087,7 +5055,7 @@ fn airAtomicStore( |
| 5087 | 5055 | return .none; |
| 5088 | 5056 | } |
| 5089 | 5057 | |
| 5090 | | fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 5058 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value { |
| 5091 | 5059 | const o = self.object; |
| 5092 | 5060 | const pt = self.pt; |
| 5093 | 5061 | const zcu = pt.zcu; |
| ... | ... | @@ -5186,7 +5154,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value |
| 5186 | 5154 | const body_block = try self.wip.block(1, "InlineMemsetBody"); |
| 5187 | 5155 | const end_block = try self.wip.block(1, "InlineMemsetEnd"); |
| 5188 | 5156 | |
| 5189 | | const llvm_usize_ty = try o.lowerType(pt, Type.usize); |
| 5157 | const llvm_usize_ty = try self.lowerType(Type.usize); |
| 5190 | 5158 | const end_ptr = switch (ptr_ty.ptrSize(zcu)) { |
| 5191 | 5159 | .slice => try self.ptraddScaled( |
| 5192 | 5160 | dest_ptr, |
| ... | ... | @@ -5225,7 +5193,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value |
| 5225 | 5193 | return .none; |
| 5226 | 5194 | } |
| 5227 | 5195 | |
| 5228 | | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5196 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5229 | 5197 | const pt = self.pt; |
| 5230 | 5198 | const zcu = pt.zcu; |
| 5231 | 5199 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -5254,7 +5222,7 @@ fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5254 | 5222 | return .none; |
| 5255 | 5223 | } |
| 5256 | 5224 | |
| 5257 | | fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5225 | fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5258 | 5226 | const pt = self.pt; |
| 5259 | 5227 | const zcu = pt.zcu; |
| 5260 | 5228 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | ... | @@ -5279,14 +5247,15 @@ fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5279 | 5247 | return .none; |
| 5280 | 5248 | } |
| 5281 | 5249 | |
| 5282 | | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5250 | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5283 | 5251 | const pt = self.pt; |
| 5284 | 5252 | const zcu = pt.zcu; |
| 5285 | 5253 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5286 | 5254 | const un_ptr_ty = self.typeOf(bin_op.lhs); |
| 5287 | 5255 | const un_ty = un_ptr_ty.childType(zcu); |
| 5288 | 5256 | const layout = un_ty.unionGetLayout(zcu); |
| 5289 | | assert(layout.tag_size != 0); |
| 5257 | |
| 5258 | if (layout.tag_size == 0) return .none; // TODO: stop Sema emitting this |
| 5290 | 5259 | |
| 5291 | 5260 | const access_kind: Builder.MemoryAccessKind = |
| 5292 | 5261 | if (un_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| ... | ... | @@ -5309,7 +5278,7 @@ fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5309 | 5278 | return .none; |
| 5310 | 5279 | } |
| 5311 | 5280 | |
| 5312 | | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5281 | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5313 | 5282 | const o = self.object; |
| 5314 | 5283 | const pt = self.pt; |
| 5315 | 5284 | const zcu = pt.zcu; |
| ... | ... | @@ -5319,7 +5288,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5319 | 5288 | assert(layout.tag_size != 0); |
| 5320 | 5289 | const union_ptr = try self.resolveInst(ty_op.operand); |
| 5321 | 5290 | if (isByRef(un_ty, zcu)) { |
| 5322 | | const llvm_un_ty = try o.lowerType(pt, un_ty); |
| 5291 | const llvm_un_ty = try self.lowerType(un_ty); |
| 5323 | 5292 | if (layout.payload_size == 0) |
| 5324 | 5293 | return self.wip.load(.normal, llvm_un_ty, union_ptr, .default, ""); |
| 5325 | 5294 | const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align)); |
| ... | ... | @@ -5333,7 +5302,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5333 | 5302 | } |
| 5334 | 5303 | } |
| 5335 | 5304 | |
| 5336 | | fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !Builder.Value { |
| 5305 | fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) Allocator.Error!Builder.Value { |
| 5337 | 5306 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5338 | 5307 | const operand = try self.resolveInst(un_op); |
| 5339 | 5308 | const operand_ty = self.typeOf(un_op); |
| ... | ... | @@ -5341,7 +5310,7 @@ fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !Build |
| 5341 | 5310 | return self.buildFloatOp(op, .normal, operand_ty, 1, .{operand}); |
| 5342 | 5311 | } |
| 5343 | 5312 | |
| 5344 | | fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 5313 | fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 5345 | 5314 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5346 | 5315 | const operand = try self.resolveInst(un_op); |
| 5347 | 5316 | const operand_ty = self.typeOf(un_op); |
| ... | ... | @@ -5349,9 +5318,7 @@ fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 5349 | 5318 | return self.buildFloatOp(.neg, fast, operand_ty, 1, .{operand}); |
| 5350 | 5319 | } |
| 5351 | 5320 | |
| 5352 | | fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value { |
| 5353 | | const o = self.object; |
| 5354 | | const pt = self.pt; |
| 5321 | fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { |
| 5355 | 5322 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5356 | 5323 | const inst_ty = self.typeOfIndex(inst); |
| 5357 | 5324 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -5361,16 +5328,14 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) |
| 5361 | 5328 | .normal, |
| 5362 | 5329 | .none, |
| 5363 | 5330 | intrinsic, |
| 5364 | | &.{try o.lowerType(pt, operand_ty)}, |
| 5331 | &.{try self.lowerType(operand_ty)}, |
| 5365 | 5332 | &.{ operand, .false }, |
| 5366 | 5333 | "", |
| 5367 | 5334 | ); |
| 5368 | | return self.wip.conv(.unsigned, result, try o.lowerType(pt, inst_ty), ""); |
| 5335 | return self.wip.conv(.unsigned, result, try self.lowerType(inst_ty), ""); |
| 5369 | 5336 | } |
| 5370 | 5337 | |
| 5371 | | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value { |
| 5372 | | const o = self.object; |
| 5373 | | const pt = self.pt; |
| 5338 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { |
| 5374 | 5339 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5375 | 5340 | const inst_ty = self.typeOfIndex(inst); |
| 5376 | 5341 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -5380,14 +5345,14 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) |
| 5380 | 5345 | .normal, |
| 5381 | 5346 | .none, |
| 5382 | 5347 | intrinsic, |
| 5383 | | &.{try o.lowerType(pt, operand_ty)}, |
| 5348 | &.{try self.lowerType(operand_ty)}, |
| 5384 | 5349 | &.{operand}, |
| 5385 | 5350 | "", |
| 5386 | 5351 | ); |
| 5387 | | return self.wip.conv(.unsigned, result, try o.lowerType(pt, inst_ty), ""); |
| 5352 | return self.wip.conv(.unsigned, result, try self.lowerType(inst_ty), ""); |
| 5388 | 5353 | } |
| 5389 | 5354 | |
| 5390 | | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5355 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5391 | 5356 | const o = self.object; |
| 5392 | 5357 | const pt = self.pt; |
| 5393 | 5358 | const zcu = pt.zcu; |
| ... | ... | @@ -5398,7 +5363,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5398 | 5363 | |
| 5399 | 5364 | const inst_ty = self.typeOfIndex(inst); |
| 5400 | 5365 | var operand = try self.resolveInst(ty_op.operand); |
| 5401 | | var llvm_operand_ty = try o.lowerType(pt, operand_ty); |
| 5366 | var llvm_operand_ty = try self.lowerType(operand_ty); |
| 5402 | 5367 | |
| 5403 | 5368 | if (bits % 16 == 8) { |
| 5404 | 5369 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte |
| ... | ... | @@ -5419,10 +5384,10 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5419 | 5384 | |
| 5420 | 5385 | const result = |
| 5421 | 5386 | try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, ""); |
| 5422 | | return self.wip.conv(.unsigned, result, try o.lowerType(pt, inst_ty), ""); |
| 5387 | return self.wip.conv(.unsigned, result, try self.lowerType(inst_ty), ""); |
| 5423 | 5388 | } |
| 5424 | 5389 | |
| 5425 | | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5390 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5426 | 5391 | const o = self.object; |
| 5427 | 5392 | const pt = self.pt; |
| 5428 | 5393 | const zcu = pt.zcu; |
| ... | ... | @@ -5440,7 +5405,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5440 | 5405 | |
| 5441 | 5406 | for (0..names.len) |name_index| { |
| 5442 | 5407 | const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?; |
| 5443 | | const this_tag_int_value = try o.builder.intConst(try o.errorIntType(pt), err_int); |
| 5408 | const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int); |
| 5444 | 5409 | try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip); |
| 5445 | 5410 | } |
| 5446 | 5411 | self.wip.cursor = .{ .block = valid_block }; |
| ... | ... | @@ -5455,13 +5420,13 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5455 | 5420 | return phi.toValue(); |
| 5456 | 5421 | } |
| 5457 | 5422 | |
| 5458 | | fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5423 | fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5459 | 5424 | const o = self.object; |
| 5460 | 5425 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5461 | 5426 | const operand = try self.resolveInst(un_op); |
| 5462 | 5427 | const enum_ty = self.typeOf(un_op); |
| 5463 | 5428 | |
| 5464 | | const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty); |
| 5429 | const llvm_fn = try o.getIsNamedEnumValueFunction(self.pt, enum_ty); |
| 5465 | 5430 | return self.wip.call( |
| 5466 | 5431 | .normal, |
| 5467 | 5432 | .fastcc, |
| ... | ... | @@ -5473,28 +5438,7 @@ fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5473 | 5438 | ); |
| 5474 | 5439 | } |
| 5475 | 5440 | |
| 5476 | | fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index { |
| 5477 | | const o = self.object; |
| 5478 | | const pt = self.pt; |
| 5479 | | const zcu = pt.zcu; |
| 5480 | | const ip = &zcu.intern_pool; |
| 5481 | | |
| 5482 | | const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern()); |
| 5483 | | if (gop.found_existing) return gop.value_ptr.*; |
| 5484 | | errdefer assert(o.named_enum_map.remove(enum_ty.toIntern())); |
| 5485 | | const function_index = try o.builder.addFunction( |
| 5486 | | // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type. |
| 5487 | | // TODO: change the builder API so we don't need to do this. |
| 5488 | | try o.builder.fnType(.void, &.{}, .normal), |
| 5489 | | try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}), |
| 5490 | | toLlvmAddressSpace(.generic, zcu.getTarget()), |
| 5491 | | ); |
| 5492 | | gop.value_ptr.* = function_index; |
| 5493 | | try o.updateIsNamedEnumValueFunction(pt, enum_ty, function_index); |
| 5494 | | return function_index; |
| 5495 | | } |
| 5496 | | |
| 5497 | | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5441 | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5498 | 5442 | const o = self.object; |
| 5499 | 5443 | const pt = self.pt; |
| 5500 | 5444 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| ... | ... | @@ -5513,34 +5457,31 @@ fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5513 | 5457 | ); |
| 5514 | 5458 | } |
| 5515 | 5459 | |
| 5516 | | fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5460 | fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5517 | 5461 | const o = self.object; |
| 5518 | 5462 | const pt = self.pt; |
| 5519 | 5463 | const zcu = pt.zcu; |
| 5520 | 5464 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5521 | 5465 | const operand = try self.resolveInst(un_op); |
| 5522 | 5466 | const slice_ty = self.typeOfIndex(inst); |
| 5523 | | const slice_llvm_ty = try o.lowerType(pt, slice_ty); |
| 5467 | const slice_llvm_ty = try self.lowerType(slice_ty); |
| 5524 | 5468 | |
| 5525 | 5469 | // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed. |
| 5526 | | const operand_usize = try self.wip.conv(.unsigned, operand, try o.lowerType(pt, .usize), ""); |
| 5470 | const operand_usize = try self.wip.conv(.unsigned, operand, try self.lowerType(.usize), ""); |
| 5527 | 5471 | |
| 5528 | | const error_name_table_ptr = try self.getErrorNameTable(); |
| 5529 | | const error_name_table = try self.wip.load(.normal, .ptr, error_name_table_ptr.toValue(&o.builder), .default, ""); |
| 5530 | | const error_name_ptr = try self.ptraddScaled(error_name_table, operand_usize, slice_ty.abiSize(zcu)); |
| 5472 | const error_name_table_ptr = try o.getErrorNameTable(); |
| 5473 | const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu)); |
| 5531 | 5474 | return self.wip.load(.normal, slice_llvm_ty, error_name_ptr, .default, ""); |
| 5532 | 5475 | } |
| 5533 | 5476 | |
| 5534 | | fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5535 | | const o = self.object; |
| 5536 | | const pt = self.pt; |
| 5477 | fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5537 | 5478 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5538 | 5479 | const scalar = try self.resolveInst(ty_op.operand); |
| 5539 | 5480 | const vector_ty = self.typeOfIndex(inst); |
| 5540 | | return self.wip.splatVector(try o.lowerType(pt, vector_ty), scalar, ""); |
| 5481 | return self.wip.splatVector(try self.lowerType(vector_ty), scalar, ""); |
| 5541 | 5482 | } |
| 5542 | 5483 | |
| 5543 | | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5484 | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5544 | 5485 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5545 | 5486 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 5546 | 5487 | const pred = try self.resolveInst(pl_op.operand); |
| ... | ... | @@ -5550,7 +5491,7 @@ fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5550 | 5491 | return self.wip.select(.normal, pred, a, b, ""); |
| 5551 | 5492 | } |
| 5552 | 5493 | |
| 5553 | | fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5494 | fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5554 | 5495 | const o = fg.object; |
| 5555 | 5496 | const pt = fg.pt; |
| 5556 | 5497 | const zcu = pt.zcu; |
| ... | ... | @@ -5561,9 +5502,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5561 | 5502 | const operand = try fg.resolveInst(unwrapped.operand); |
| 5562 | 5503 | const mask = unwrapped.mask; |
| 5563 | 5504 | const operand_ty = fg.typeOf(unwrapped.operand); |
| 5564 | | const llvm_operand_ty = try o.lowerType(pt, operand_ty); |
| 5565 | | const llvm_result_ty = try o.lowerType(pt, unwrapped.result_ty); |
| 5566 | | const llvm_elem_ty = try o.lowerType(pt, unwrapped.result_ty.childType(zcu)); |
| 5505 | const llvm_operand_ty = try fg.lowerType(operand_ty); |
| 5506 | const llvm_result_ty = try fg.lowerType(unwrapped.result_ty); |
| 5507 | const llvm_elem_ty = try fg.lowerType(unwrapped.result_ty.childType(zcu)); |
| 5567 | 5508 | const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty); |
| 5568 | 5509 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 5569 | 5510 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); |
| ... | ... | @@ -5657,7 +5598,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5657 | 5598 | ); |
| 5658 | 5599 | } |
| 5659 | 5600 | |
| 5660 | | fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5601 | fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5661 | 5602 | const o = fg.object; |
| 5662 | 5603 | const pt = fg.pt; |
| 5663 | 5604 | const zcu = pt.zcu; |
| ... | ... | @@ -5666,7 +5607,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5666 | 5607 | const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst); |
| 5667 | 5608 | |
| 5668 | 5609 | const mask = unwrapped.mask; |
| 5669 | | const llvm_elem_ty = try o.lowerType(pt, unwrapped.result_ty.childType(zcu)); |
| 5610 | const llvm_elem_ty = try fg.lowerType(unwrapped.result_ty.childType(zcu)); |
| 5670 | 5611 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); |
| 5671 | 5612 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 5672 | 5613 | |
| ... | ... | @@ -5756,10 +5697,9 @@ fn buildReducedCall( |
| 5756 | 5697 | operand_vector: Builder.Value, |
| 5757 | 5698 | vector_len: usize, |
| 5758 | 5699 | accum_init: Builder.Value, |
| 5759 | | ) !Builder.Value { |
| 5700 | ) Allocator.Error!Builder.Value { |
| 5760 | 5701 | const o = self.object; |
| 5761 | | const pt = self.pt; |
| 5762 | | const usize_ty = try o.lowerType(pt, Type.usize); |
| 5702 | const usize_ty = try self.lowerType(Type.usize); |
| 5763 | 5703 | const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len); |
| 5764 | 5704 | const llvm_result_ty = accum_init.typeOfWip(&self.wip); |
| 5765 | 5705 | |
| ... | ... | @@ -5811,7 +5751,7 @@ fn buildReducedCall( |
| 5811 | 5751 | return self.wip.load(.normal, llvm_result_ty, accum_ptr, .default, ""); |
| 5812 | 5752 | } |
| 5813 | 5753 | |
| 5814 | | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value { |
| 5754 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value { |
| 5815 | 5755 | const o = self.object; |
| 5816 | 5756 | const pt = self.pt; |
| 5817 | 5757 | const zcu = pt.zcu; |
| ... | ... | @@ -5820,9 +5760,9 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! |
| 5820 | 5760 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 5821 | 5761 | const operand = try self.resolveInst(reduce.operand); |
| 5822 | 5762 | const operand_ty = self.typeOf(reduce.operand); |
| 5823 | | const llvm_operand_ty = try o.lowerType(pt, operand_ty); |
| 5763 | const llvm_operand_ty = try self.lowerType(operand_ty); |
| 5824 | 5764 | const scalar_ty = self.typeOfIndex(inst); |
| 5825 | | const llvm_scalar_ty = try o.lowerType(pt, scalar_ty); |
| 5765 | const llvm_scalar_ty = try self.lowerType(scalar_ty); |
| 5826 | 5766 | |
| 5827 | 5767 | switch (reduce.operation) { |
| 5828 | 5768 | .And, .Or, .Xor => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { |
| ... | ... | @@ -5890,8 +5830,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! |
| 5890 | 5830 | else => unreachable, |
| 5891 | 5831 | }; |
| 5892 | 5832 | |
| 5893 | | const libc_fn = |
| 5894 | | try self.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty); |
| 5833 | const libc_fn = try o.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty); |
| 5895 | 5834 | const init_val = switch (llvm_scalar_ty) { |
| 5896 | 5835 | .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast( |
| 5897 | 5836 | @as(f16, switch (reduce.operation) { |
| ... | ... | @@ -5922,7 +5861,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! |
| 5922 | 5861 | return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val); |
| 5923 | 5862 | } |
| 5924 | 5863 | |
| 5925 | | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5864 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5926 | 5865 | const o = self.object; |
| 5927 | 5866 | const pt = self.pt; |
| 5928 | 5867 | const zcu = pt.zcu; |
| ... | ... | @@ -5931,7 +5870,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5931 | 5870 | const result_ty = self.typeOfIndex(inst); |
| 5932 | 5871 | const len: usize = @intCast(result_ty.arrayLen(zcu)); |
| 5933 | 5872 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]); |
| 5934 | | const llvm_result_ty = try o.lowerType(pt, result_ty); |
| 5873 | const llvm_result_ty = try self.lowerType(result_ty); |
| 5935 | 5874 | |
| 5936 | 5875 | switch (result_ty.zigTypeTag(zcu)) { |
| 5937 | 5876 | .vector => { |
| ... | ... | @@ -5997,7 +5936,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5997 | 5936 | field_ptr_align.toLlvm(), |
| 5998 | 5937 | llvm_field_val, |
| 5999 | 5938 | field_ty.abiAlignment(zcu).toLlvm(), |
| 6000 | | try o.builder.intValue(try o.lowerType(pt, .usize), field_ty.abiSize(zcu)), |
| 5939 | try o.builder.intValue(try self.lowerType(.usize), field_ty.abiSize(zcu)), |
| 6001 | 5940 | .normal, |
| 6002 | 5941 | self.disable_intrinsics, |
| 6003 | 5942 | ); |
| ... | ... | @@ -6042,7 +5981,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6042 | 5981 | } |
| 6043 | 5982 | } |
| 6044 | 5983 | |
| 6045 | | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5984 | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6046 | 5985 | const o = self.object; |
| 6047 | 5986 | const pt = self.pt; |
| 6048 | 5987 | const zcu = pt.zcu; |
| ... | ... | @@ -6050,7 +5989,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6050 | 5989 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6051 | 5990 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 6052 | 5991 | const union_ty = self.typeOfIndex(inst); |
| 6053 | | const union_llvm_ty = try o.lowerType(pt, union_ty); |
| 5992 | const union_llvm_ty = try self.lowerType(union_ty); |
| 6054 | 5993 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 6055 | 5994 | |
| 6056 | 5995 | assert(union_obj.layout != .@"packed"); |
| ... | ... | @@ -6086,7 +6025,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6086 | 6025 | return result_ptr; |
| 6087 | 6026 | } |
| 6088 | 6027 | |
| 6089 | | fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6028 | fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6090 | 6029 | const o = self.object; |
| 6091 | 6030 | const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch; |
| 6092 | 6031 | |
| ... | ... | @@ -6135,14 +6074,12 @@ fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6135 | 6074 | return .none; |
| 6136 | 6075 | } |
| 6137 | 6076 | |
| 6138 | | fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6139 | | const o = self.object; |
| 6140 | | const pt = self.pt; |
| 6077 | fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6141 | 6078 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6142 | 6079 | const inst_ty = self.typeOfIndex(inst); |
| 6143 | 6080 | const operand = try self.resolveInst(ty_op.operand); |
| 6144 | 6081 | |
| 6145 | | return self.wip.cast(.addrspacecast, operand, try o.lowerType(pt, inst_ty), ""); |
| 6082 | return self.wip.cast(.addrspacecast, operand, try self.lowerType(inst_ty), ""); |
| 6146 | 6083 | } |
| 6147 | 6084 | |
| 6148 | 6085 | fn workIntrinsic( |
| ... | ... | @@ -6150,7 +6087,7 @@ fn workIntrinsic( |
| 6150 | 6087 | dimension: u32, |
| 6151 | 6088 | default: u32, |
| 6152 | 6089 | comptime basename: []const u8, |
| 6153 | | ) !Builder.Value { |
| 6090 | ) Allocator.Error!Builder.Value { |
| 6154 | 6091 | return self.wip.callIntrinsic(.normal, .none, switch (dimension) { |
| 6155 | 6092 | 0 => @field(Builder.Intrinsic, basename ++ ".x"), |
| 6156 | 6093 | 1 => @field(Builder.Intrinsic, basename ++ ".y"), |
| ... | ... | @@ -6159,7 +6096,7 @@ fn workIntrinsic( |
| 6159 | 6096 | }, &.{}, &.{}, ""); |
| 6160 | 6097 | } |
| 6161 | 6098 | |
| 6162 | | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6099 | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6163 | 6100 | const target = self.pt.zcu.getTarget(); |
| 6164 | 6101 | |
| 6165 | 6102 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | ... | @@ -6172,7 +6109,7 @@ fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6172 | 6109 | }; |
| 6173 | 6110 | } |
| 6174 | 6111 | |
| 6175 | | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6112 | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6176 | 6113 | const pt = self.pt; |
| 6177 | 6114 | const target = pt.zcu.getTarget(); |
| 6178 | 6115 | |
| ... | ... | @@ -6200,7 +6137,7 @@ fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6200 | 6137 | } |
| 6201 | 6138 | } |
| 6202 | 6139 | |
| 6203 | | fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6140 | fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6204 | 6141 | const target = self.pt.zcu.getTarget(); |
| 6205 | 6142 | |
| 6206 | 6143 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| ... | ... | @@ -6213,28 +6150,6 @@ fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6213 | 6150 | }; |
| 6214 | 6151 | } |
| 6215 | 6152 | |
| 6216 | | fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index { |
| 6217 | | const o = self.object; |
| 6218 | | const pt = self.pt; |
| 6219 | | |
| 6220 | | const table = o.error_name_table; |
| 6221 | | if (table != .none) return table; |
| 6222 | | |
| 6223 | | // TODO: Address space |
| 6224 | | const variable_index = |
| 6225 | | try o.builder.addVariable(try o.builder.strtabString("__zig_err_name_table"), .ptr, .default); |
| 6226 | | variable_index.setLinkage(.private, &o.builder); |
| 6227 | | variable_index.setMutability(.constant, &o.builder); |
| 6228 | | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 6229 | | variable_index.setAlignment( |
| 6230 | | Type.slice_const_u8_sentinel_0.abiAlignment(pt.zcu).toLlvm(), |
| 6231 | | &o.builder, |
| 6232 | | ); |
| 6233 | | |
| 6234 | | o.error_name_table = variable_index; |
| 6235 | | return variable_index; |
| 6236 | | } |
| 6237 | | |
| 6238 | 6153 | /// Assumes that `Type.optionalReprIsPayload` is `false` for `opt_ty` and that the payload has bits. |
| 6239 | 6154 | fn optCmpNull( |
| 6240 | 6155 | self: *FuncGen, |
| ... | ... | @@ -6258,7 +6173,7 @@ fn optPayloadHandle( |
| 6258 | 6173 | opt_ptr: Builder.Value, |
| 6259 | 6174 | opt_ty: Type, |
| 6260 | 6175 | can_elide_load: bool, |
| 6261 | | ) !Builder.Value { |
| 6176 | ) Allocator.Error!Builder.Value { |
| 6262 | 6177 | const pt = fg.pt; |
| 6263 | 6178 | const zcu = pt.zcu; |
| 6264 | 6179 | assert(isByRef(opt_ty, zcu)); |
| ... | ... | @@ -6281,7 +6196,7 @@ fn fieldPtr( |
| 6281 | 6196 | aggregate_ptr: Builder.Value, |
| 6282 | 6197 | aggregate_ptr_ty: Type, |
| 6283 | 6198 | field_index: u32, |
| 6284 | | ) !Builder.Value { |
| 6199 | ) Allocator.Error!Builder.Value { |
| 6285 | 6200 | const pt = self.pt; |
| 6286 | 6201 | const zcu = pt.zcu; |
| 6287 | 6202 | const aggregate_ty = aggregate_ptr_ty.childType(zcu); |
| ... | ... | @@ -6305,7 +6220,7 @@ fn loadTruncate( |
| 6305 | 6220 | payload_ty: Type, |
| 6306 | 6221 | payload_ptr: Builder.Value, |
| 6307 | 6222 | payload_alignment: Builder.Alignment, |
| 6308 | | ) !Builder.Value { |
| 6223 | ) Allocator.Error!Builder.Value { |
| 6309 | 6224 | // from https://llvm.org/docs/LangRef.html#load-instruction : |
| 6310 | 6225 | // "When loading a value of a type like i20 with a size that is not an integral number of bytes, the result is undefined if the value was not originally written using a store of the same type. " |
| 6311 | 6226 | // => so load the byte aligned value and trunc the unwanted bits. |
| ... | ... | @@ -6313,7 +6228,7 @@ fn loadTruncate( |
| 6313 | 6228 | const o = fg.object; |
| 6314 | 6229 | const pt = fg.pt; |
| 6315 | 6230 | const zcu = pt.zcu; |
| 6316 | | const payload_llvm_ty = try o.lowerType(pt, payload_ty); |
| 6231 | const payload_llvm_ty = try fg.lowerType(payload_ty); |
| 6317 | 6232 | const abi_size = payload_ty.abiSize(zcu); |
| 6318 | 6233 | |
| 6319 | 6234 | const load_llvm_ty = if (payload_ty.isAbiInt(zcu)) |
| ... | ... | @@ -6321,7 +6236,7 @@ fn loadTruncate( |
| 6321 | 6236 | else |
| 6322 | 6237 | payload_llvm_ty; |
| 6323 | 6238 | const loaded = try fg.wip.load(access_kind, load_llvm_ty, payload_ptr, payload_alignment, ""); |
| 6324 | | const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big) |
| 6239 | const shifted = if (payload_llvm_ty != load_llvm_ty and zcu.getTarget().cpu.arch.endian() == .big) |
| 6325 | 6240 | try fg.wip.bin(.lshr, loaded, try o.builder.intValue( |
| 6326 | 6241 | load_llvm_ty, |
| 6327 | 6242 | (payload_ty.abiSize(zcu) - (std.math.divCeil(u64, payload_ty.bitSize(zcu), 8) catch unreachable)) * 8, |
| ... | ... | @@ -6339,10 +6254,10 @@ fn loadByRef( |
| 6339 | 6254 | pointee_type: Type, |
| 6340 | 6255 | ptr_alignment: Builder.Alignment, |
| 6341 | 6256 | access_kind: Builder.MemoryAccessKind, |
| 6342 | | ) !Builder.Value { |
| 6257 | ) Allocator.Error!Builder.Value { |
| 6343 | 6258 | const o = fg.object; |
| 6344 | 6259 | const pt = fg.pt; |
| 6345 | | const pointee_llvm_ty = try o.lowerType(pt, pointee_type); |
| 6260 | const pointee_llvm_ty = try fg.lowerType(pointee_type); |
| 6346 | 6261 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment) |
| 6347 | 6262 | .max(pointee_type.abiAlignment(pt.zcu)).toLlvm(); |
| 6348 | 6263 | const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align); |
| ... | ... | @@ -6352,7 +6267,7 @@ fn loadByRef( |
| 6352 | 6267 | result_align, |
| 6353 | 6268 | ptr, |
| 6354 | 6269 | ptr_alignment, |
| 6355 | | try o.builder.intValue(try o.lowerType(pt, Type.usize), size_bytes), |
| 6270 | try o.builder.intValue(try fg.lowerType(.usize), size_bytes), |
| 6356 | 6271 | access_kind, |
| 6357 | 6272 | fg.disable_intrinsics, |
| 6358 | 6273 | ); |
| ... | ... | @@ -6362,7 +6277,7 @@ fn loadByRef( |
| 6362 | 6277 | /// This function always performs a copy. For isByRef=true types, it creates a new |
| 6363 | 6278 | /// alloca and copies the value into it, then returns the alloca instruction. |
| 6364 | 6279 | /// For isByRef=false types, it creates a load instruction and returns it. |
| 6365 | | fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 6280 | fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) Allocator.Error!Builder.Value { |
| 6366 | 6281 | const o = self.object; |
| 6367 | 6282 | const pt = self.pt; |
| 6368 | 6283 | const zcu = pt.zcu; |
| ... | ... | @@ -6380,7 +6295,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 6380 | 6295 | |
| 6381 | 6296 | if (info.flags.vector_index != .none) { |
| 6382 | 6297 | const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index); |
| 6383 | | const vec_elem_ty = try o.lowerType(pt, elem_ty); |
| 6298 | const vec_elem_ty = try self.lowerType(elem_ty); |
| 6384 | 6299 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); |
| 6385 | 6300 | |
| 6386 | 6301 | const loaded_vector = try self.wip.load(access_kind, vec_ty, ptr, ptr_alignment, ""); |
| ... | ... | @@ -6401,7 +6316,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 6401 | 6316 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); |
| 6402 | 6317 | const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset); |
| 6403 | 6318 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); |
| 6404 | | const elem_llvm_ty = try o.lowerType(pt, elem_ty); |
| 6319 | const elem_llvm_ty = try self.lowerType(elem_ty); |
| 6405 | 6320 | |
| 6406 | 6321 | if (isByRef(elem_ty, zcu)) { |
| 6407 | 6322 | const result_align = elem_ty.abiAlignment(zcu).toLlvm(); |
| ... | ... | @@ -6434,7 +6349,7 @@ fn store( |
| 6434 | 6349 | ptr_ty: Type, |
| 6435 | 6350 | elem: Builder.Value, |
| 6436 | 6351 | ordering: Builder.AtomicOrdering, |
| 6437 | | ) !void { |
| 6352 | ) Allocator.Error!void { |
| 6438 | 6353 | const o = self.object; |
| 6439 | 6354 | const pt = self.pt; |
| 6440 | 6355 | const zcu = pt.zcu; |
| ... | ... | @@ -6449,7 +6364,7 @@ fn store( |
| 6449 | 6364 | |
| 6450 | 6365 | if (info.flags.vector_index != .none) { |
| 6451 | 6366 | const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index); |
| 6452 | | const vec_elem_ty = try o.lowerType(pt, elem_ty); |
| 6367 | const vec_elem_ty = try self.lowerType(elem_ty); |
| 6453 | 6368 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); |
| 6454 | 6369 | |
| 6455 | 6370 | const loaded_vector = try self.wip.load(.normal, vec_ty, ptr, ptr_alignment, ""); |
| ... | ... | @@ -6518,7 +6433,7 @@ fn store( |
| 6518 | 6433 | ptr_alignment, |
| 6519 | 6434 | elem, |
| 6520 | 6435 | elem_ty.abiAlignment(zcu).toLlvm(), |
| 6521 | | try o.builder.intValue(try o.lowerType(pt, Type.usize), elem_ty.abiSize(zcu)), |
| 6436 | try o.builder.intValue(try self.lowerType(Type.usize), elem_ty.abiSize(zcu)), |
| 6522 | 6437 | access_kind, |
| 6523 | 6438 | self.disable_intrinsics, |
| 6524 | 6439 | ); |
| ... | ... | @@ -6527,8 +6442,7 @@ fn store( |
| 6527 | 6442 | fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void { |
| 6528 | 6443 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; |
| 6529 | 6444 | const o = fg.object; |
| 6530 | | const pt = fg.pt; |
| 6531 | | const usize_ty = try o.lowerType(pt, Type.usize); |
| 6445 | const usize_ty = try fg.lowerType(.usize); |
| 6532 | 6446 | const zero = try o.builder.intValue(usize_ty, 0); |
| 6533 | 6447 | const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED); |
| 6534 | 6448 | const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, ""); |
| ... | ... | @@ -6551,7 +6465,7 @@ fn valgrindClientRequest( |
| 6551 | 6465 | const target = zcu.getTarget(); |
| 6552 | 6466 | if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value; |
| 6553 | 6467 | |
| 6554 | | const llvm_usize = try o.lowerType(pt, Type.usize); |
| 6468 | const llvm_usize = try fg.lowerType(.usize); |
| 6555 | 6469 | const usize_alignment = Type.usize.abiAlignment(zcu).toLlvm(); |
| 6556 | 6470 | |
| 6557 | 6471 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); |
| ... | ... | @@ -7360,11 +7274,12 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool { |
| 7360 | 7274 | => false, |
| 7361 | 7275 | |
| 7362 | 7276 | .array, |
| 7363 | | .error_union, |
| 7364 | 7277 | .frame, |
| 7365 | 7278 | => ty.hasRuntimeBits(zcu), |
| 7366 | 7279 | |
| 7367 | | .optional => ty.hasRuntimeBits(zcu) and !ty.optionalReprIsPayload(zcu), |
| 7280 | .error_union => ty.errorUnionPayload(zcu).hasRuntimeBits(zcu), |
| 7281 | |
| 7282 | .optional => !ty.optionalReprIsPayload(zcu) and ty.optionalChild(zcu).hasRuntimeBits(zcu), |
| 7368 | 7283 | |
| 7369 | 7284 | .@"struct" => switch (ty.containerLayout(zcu)) { |
| 7370 | 7285 | .@"packed" => false, |
| ... | ... | @@ -7402,25 +7317,19 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E |
| 7402 | 7317 | |
| 7403 | 7318 | fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value { |
| 7404 | 7319 | if (offset == 0) return ptr; |
| 7405 | | const llvm_usize_ty = try fg.object.lowerType(fg.pt, .usize); |
| 7320 | const llvm_usize_ty = try fg.lowerType(.usize); |
| 7406 | 7321 | const offset_val = try fg.object.builder.intValue(llvm_usize_ty, offset); |
| 7407 | | return fg.ptradd(ptr, offset_val); |
| 7322 | return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, ""); |
| 7408 | 7323 | } |
| 7409 | 7324 | fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u64) Allocator.Error!Builder.Value { |
| 7410 | | switch (scale) { |
| 7411 | | 0 => return ptr, |
| 7412 | | 1 => return fg.ptradd(ptr, index), |
| 7413 | | else => { |
| 7414 | | const o = fg.object; |
| 7415 | | const llvm_usize_ty = try o.lowerType(fg.pt, .usize); |
| 7416 | | const scale_val = try o.builder.intValue(llvm_usize_ty, scale); |
| 7417 | | const offset = try fg.wip.bin(.@"mul nuw", index, scale_val, ""); |
| 7418 | | return fg.ptradd(ptr, offset); |
| 7419 | | }, |
| 7420 | | } |
| 7421 | | } |
| 7422 | | fn ptradd(fg: *FuncGen, ptr: Builder.Value, offset: Builder.Value) Allocator.Error!Builder.Value { |
| 7423 | | return fg.wip.gep(.inbounds, .i8, ptr, &.{offset}, ""); |
| 7325 | if (scale == 0) return ptr; |
| 7326 | // Right now LLVM seems to fare a bit worse with an explicit `mul nuw` instruction than it does |
| 7327 | // if we use a bigger type for the GEP, so we'll do that. As I understand it, it has not yet |
| 7328 | // been decided whether the planned `ptradd` instruction will accept a scale or not; if it does |
| 7329 | // not then presumably upstream will improve their handling of explicit `mul nuw` computing the |
| 7330 | // offset. |
| 7331 | const llvm_scale_ty = try fg.object.builder.arrayType(scale, .i8); |
| 7332 | return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, ""); |
| 7424 | 7333 | } |
| 7425 | 7334 | |
| 7426 | 7335 | fn compilerRtIntBits(bits: u16) ?u16 { |