| ... | @@ -1,7 +1,5 @@ | ... | @@ -1,7 +1,5 @@ |
| 1 | const FuncGen = @This(); | 1 | const FuncGen = @This(); |
| 2 | | 2 | |
| 3 | pub const Error = Zcu.CodegenFailError; | | |
| 4 | | | |
| 5 | object: *Object, | 3 | object: *Object, |
| 6 | nav_index: InternPool.Nav.Index, | 4 | nav_index: InternPool.Nav.Index, |
| 7 | pt: Zcu.PerThread, | 5 | pt: Zcu.PerThread, |
| ... | @@ -63,7 +61,17 @@ disable_intrinsics: bool, | ... | @@ -63,7 +61,17 @@ disable_intrinsics: bool, |
| 63 | /// Have we seen loads or stores involving `allowzero` pointers? | 61 | /// Have we seen loads or stores involving `allowzero` pointers? |
| 64 | allowzero_access: bool, | 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 | @branchHint(.cold); | 75 | @branchHint(.cold); |
| 68 | return fg.pt.zcu.codegenFail( | 76 | return fg.pt.zcu.codegenFail( |
| 69 | fg.nav_index, | 77 | fg.nav_index, |
| ... | @@ -167,7 +175,11 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant { | ... | @@ -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 | const o = self.object; | 183 | const o = self.object; |
| 172 | const zcu = self.pt.zcu; | 184 | const zcu = self.pt.zcu; |
| 173 | const ip = &zcu.intern_pool; | 185 | const ip = &zcu.intern_pool; |
| ... | @@ -443,13 +455,16 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air | ... | @@ -443,13 +455,16 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air |
| 443 | | 455 | |
| 444 | // Instructions which may be `noreturn`. | 456 | // Instructions which may be `noreturn`. |
| 445 | .block => res: { | 457 | .block => res: { |
| 446 | const res = try self.airBlock(inst); | 458 | const block = self.air.unwrapBlock(inst); |
| 447 | if (self.typeOfIndex(inst).isNoReturn(zcu)) return; | 459 | const res = try self.lowerBlock(inst, null, block.body); |
| | 460 | if (block.ty.isNoReturn(zcu)) return; |
| 448 | break :res res; | 461 | break :res res; |
| 449 | }, | 462 | }, |
| 450 | .dbg_inline_block => res: { | 463 | .dbg_inline_block => res: { |
| 451 | const res = try self.airDbgInlineBlock(inst); | 464 | const block = self.air.unwrapDbgBlock(inst); |
| 452 | if (self.typeOfIndex(inst).isNoReturn(zcu)) return; | 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 | break :res res; | 468 | break :res res; |
| 454 | }, | 469 | }, |
| 455 | .call, .call_always_tail, .call_never_tail, .call_never_inline => |tag| res: { | 470 | .call, .call_always_tail, .call_never_tail, .call_never_inline => |tag| res: { |
| ... | @@ -479,7 +494,7 @@ fn genBodyDebugScope( | ... | @@ -479,7 +494,7 @@ fn genBodyDebugScope( |
| 479 | maybe_inline_func: ?InternPool.Index, | 494 | maybe_inline_func: ?InternPool.Index, |
| 480 | body: []const Air.Inst.Index, | 495 | body: []const Air.Inst.Index, |
| 481 | coverage_point: Air.CoveragePoint, | 496 | coverage_point: Air.CoveragePoint, |
| 482 | ) Error!void { | 497 | ) TodoError!void { |
| 483 | const o = self.object; | 498 | const o = self.object; |
| 484 | | 499 | |
| 485 | if (self.wip.strip) return self.genBody(body, coverage_point); | 500 | if (self.wip.strip) return self.genBody(body, coverage_point); |
| ... | @@ -508,7 +523,7 @@ fn genBodyDebugScope( | ... | @@ -508,7 +523,7 @@ fn genBodyDebugScope( |
| 508 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); | 523 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); |
| 509 | const mod = zcu.fileByIndex(file_scope).mod.?; | 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 | self.base_line = zcu.navSrcLine(func.owner_nav); | 528 | self.base_line = zcu.navSrcLine(func.owner_nav); |
| 514 | const line_number = self.base_line + 1; | 529 | const line_number = self.base_line + 1; |
| ... | @@ -562,7 +577,7 @@ const CallAttr = enum { | ... | @@ -562,7 +577,7 @@ const CallAttr = enum { |
| 562 | AlwaysInline, | 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 | const air_call = self.air.unwrapCall(inst); | 581 | const air_call = self.air.unwrapCall(inst); |
| 567 | const args = air_call.args; | 582 | const args = air_call.args; |
| 568 | const o = self.object; | 583 | const o = self.object; |
| ... | @@ -598,7 +613,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -598,7 +613,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 598 | } | 613 | } |
| 599 | | 614 | |
| 600 | const ret_ptr = if (!sret) null else blk: { | 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 | try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder); | 617 | try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder); |
| 603 | | 618 | |
| 604 | const alignment = return_type.abiAlignment(zcu).toLlvm(); | 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,7 +635,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 620 | const arg = args[it.zig_index - 1]; | 635 | const arg = args[it.zig_index - 1]; |
| 621 | const param_ty = self.typeOf(arg); | 636 | const param_ty = self.typeOf(arg); |
| 622 | const llvm_arg = try self.resolveInst(arg); | 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 | if (isByRef(param_ty, zcu)) { | 639 | if (isByRef(param_ty, zcu)) { |
| 625 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 640 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); |
| 626 | const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, ""); | 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,7 +664,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 649 | const llvm_arg = try self.resolveInst(arg); | 664 | const llvm_arg = try self.resolveInst(arg); |
| 650 | | 665 | |
| 651 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 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 | const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment); | 668 | const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment); |
| 654 | if (isByRef(param_ty, zcu)) { | 669 | if (isByRef(param_ty, zcu)) { |
| 655 | const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, ""); | 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,7 +734,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 719 | llvm_arg = ptr; | 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 | const array_ty = try o.builder.arrayType(count, float_ty); | 738 | const array_ty = try o.builder.arrayType(count, float_ty); |
| 724 | | 739 | |
| 725 | const loaded = try self.wip.load(.normal, array_ty, llvm_arg, alignment, ""); | 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,7 +775,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 760 | .byref => { | 775 | .byref => { |
| 761 | const param_index = it.zig_index - 1; | 776 | const param_index = it.zig_index - 1; |
| 762 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); | 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 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | 779 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); |
| 765 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty); | 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,7 +827,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 812 | }, | 827 | }, |
| 813 | toLlvmCallConvTag(fn_info.cc, target).?, | 828 | toLlvmCallConvTag(fn_info.cc, target).?, |
| 814 | try attributes.finish(&o.builder), | 829 | try attributes.finish(&o.builder), |
| 815 | try o.lowerType(pt, zig_fn_ty), | 830 | try self.lowerType(zig_fn_ty), |
| 816 | llvm_fn, | 831 | llvm_fn, |
| 817 | llvm_args.items, | 832 | llvm_args.items, |
| 818 | "", | 833 | "", |
| ... | @@ -826,7 +841,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -826,7 +841,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 826 | return .none; | 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 | if (ret_ptr) |rp| { | 845 | if (ret_ptr) |rp| { |
| 831 | if (isByRef(return_type, zcu)) { | 846 | if (isByRef(return_type, zcu)) { |
| 832 | return rp; | 847 | return rp; |
| ... | @@ -864,7 +879,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -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 | const o = fg.object; | 883 | const o = fg.object; |
| 869 | const pt = fg.pt; | 884 | const pt = fg.pt; |
| 870 | const zcu = pt.zcu; | 885 | const zcu = pt.zcu; |
| ... | @@ -888,7 +903,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void { | ... | @@ -888,7 +903,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void { |
| 888 | _ = try fg.wip.@"unreachable"(); | 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 | const o = self.object; | 907 | const o = self.object; |
| 893 | const pt = self.pt; | 908 | const pt = self.pt; |
| 894 | const zcu = pt.zcu; | 909 | const zcu = pt.zcu; |
| ... | @@ -910,7 +925,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -910,7 +925,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 910 | // https://github.com/ziglang/zig/issues/15337 | 925 | // https://github.com/ziglang/zig/issues/15337 |
| 911 | break :undef; | 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 | _ = try self.wip.callMemSet( | 929 | _ = try self.wip.callMemSet( |
| 915 | self.ret_ptr, | 930 | self.ret_ptr, |
| 916 | ptr_ty.ptrAlignment(zcu).toLlvm(), | 931 | ptr_ty.ptrAlignment(zcu).toLlvm(), |
| ... | @@ -946,7 +961,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -946,7 +961,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 946 | // Functions with an empty error set are emitted with an error code | 961 | // Functions with an empty error set are emitted with an error code |
| 947 | // return type and return zero so they can be function pointers coerced | 962 | // return type and return zero so they can be function pointers coerced |
| 948 | // to functions that return anyerror. | 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 | } else { | 965 | } else { |
| 951 | _ = try self.wip.retVoid(); | 966 | _ = try self.wip.retVoid(); |
| 952 | } | 967 | } |
| ... | @@ -961,7 +976,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -961,7 +976,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 961 | if (val_is_undef and safety) { | 976 | if (val_is_undef and safety) { |
| 962 | const llvm_ret_ty = operand.typeOfWip(&self.wip); | 977 | const llvm_ret_ty = operand.typeOfWip(&self.wip); |
| 963 | const rp = try self.buildAlloca(llvm_ret_ty, alignment); | 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 | _ = try self.wip.callMemSet( | 980 | _ = try self.wip.callMemSet( |
| 966 | rp, | 981 | rp, |
| 967 | alignment, | 982 | alignment, |
| ... | @@ -997,7 +1012,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -997,7 +1012,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void { |
| 997 | return; | 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 | const o = self.object; | 1016 | const o = self.object; |
| 1002 | const pt = self.pt; | 1017 | const pt = self.pt; |
| 1003 | const zcu = pt.zcu; | 1018 | const zcu = pt.zcu; |
| ... | @@ -1011,7 +1026,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { | ... | @@ -1011,7 +1026,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1011 | // Functions with an empty error set are emitted with an error code | 1026 | // Functions with an empty error set are emitted with an error code |
| 1012 | // return type and return zero so they can be function pointers coerced | 1027 | // return type and return zero so they can be function pointers coerced |
| 1013 | // to functions that return anyerror. | 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 | } else { | 1030 | } else { |
| 1016 | _ = try self.wip.retVoid(); | 1031 | _ = try self.wip.retVoid(); |
| 1017 | } | 1032 | } |
| ... | @@ -1028,25 +1043,22 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { | ... | @@ -1028,25 +1043,22 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1028 | return; | 1043 | return; |
| 1029 | } | 1044 | } |
| 1030 | | 1045 | |
| 1031 | fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 1046 | fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1032 | const o = self.object; | | |
| 1033 | const pt = self.pt; | | |
| 1034 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1047 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1035 | const list = try self.resolveInst(ty_op.operand); | 1048 | const list = try self.resolveInst(ty_op.operand); |
| 1036 | const arg_ty = ty_op.ty.toType(); | 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 | return self.wip.vaArg(list, llvm_arg_ty, ""); | 1052 | return self.wip.vaArg(list, llvm_arg_ty, ""); |
| 1040 | } | 1053 | } |
| 1041 | | 1054 | |
| 1042 | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 1055 | fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1043 | const o = self.object; | | |
| 1044 | const pt = self.pt; | 1056 | const pt = self.pt; |
| 1045 | const zcu = pt.zcu; | 1057 | const zcu = pt.zcu; |
| 1046 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1058 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1047 | const src_list = try self.resolveInst(ty_op.operand); | 1059 | const src_list = try self.resolveInst(ty_op.operand); |
| 1048 | const va_list_ty = ty_op.ty.toType(); | 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 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); | 1063 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); |
| 1052 | const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment); | 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,7 +1070,7 @@ fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1058 | try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, ""); | 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 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 1074 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 1063 | const src_list = try self.resolveInst(un_op); | 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,12 +1078,11 @@ fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1066 | return .none; | 1078 | return .none; |
| 1067 | } | 1079 | } |
| 1068 | | 1080 | |
| 1069 | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 1081 | fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 1070 | const o = self.object; | | |
| 1071 | const pt = self.pt; | 1082 | const pt = self.pt; |
| 1072 | const zcu = pt.zcu; | 1083 | const zcu = pt.zcu; |
| 1073 | const va_list_ty = self.typeOfIndex(inst); | 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 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); | 1087 | const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm(); |
| 1077 | const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment); | 1088 | const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment); |
| ... | @@ -1088,7 +1099,7 @@ fn airCmp( | ... | @@ -1088,7 +1099,7 @@ fn airCmp( |
| 1088 | inst: Air.Inst.Index, | 1099 | inst: Air.Inst.Index, |
| 1089 | op: math.CompareOperator, | 1100 | op: math.CompareOperator, |
| 1090 | fast: Builder.FastMathKind, | 1101 | fast: Builder.FastMathKind, |
| 1091 | ) !Builder.Value { | 1102 | ) Allocator.Error!Builder.Value { |
| 1092 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 1103 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 1093 | const lhs = try self.resolveInst(bin_op.lhs); | 1104 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1094 | const rhs = try self.resolveInst(bin_op.rhs); | 1105 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -1097,7 +1108,7 @@ fn airCmp( | ... | @@ -1097,7 +1108,7 @@ fn airCmp( |
| 1097 | return self.cmp(fast, op, operand_ty, lhs, rhs); | 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 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 1112 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1102 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; | 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,21 +1120,20 @@ fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind |
| 1109 | return self.cmp(fast, cmp_op, vec_ty, lhs, rhs); | 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 | const o = self.object; | 1124 | const o = self.object; |
| 1114 | const pt = self.pt; | | |
| 1115 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 1125 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 1116 | const operand = try self.resolveInst(un_op); | 1126 | const operand = try self.resolveInst(un_op); |
| 1117 | const llvm_fn = try o.getCmpLtErrorsLenFunction(pt); | 1127 | const errors_len_ptr = try o.getErrorsLen(); |
| 1118 | return self.wip.call( | 1128 | const errors_len_val = try self.wip.load( |
| 1119 | .normal, | 1129 | .normal, |
| 1120 | .fastcc, | 1130 | try o.errorIntType(), |
| 1121 | .none, | 1131 | errors_len_ptr.toValue(&o.builder), |
| 1122 | llvm_fn.typeOf(&o.builder), | 1132 | Type.errorAbiAlignment(o.zcu).toLlvm(), |
| 1123 | llvm_fn.toValue(&o.builder), | | |
| 1124 | &.{operand}, | | |
| 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 | fn cmp( | 1139 | fn cmp( |
| ... | @@ -1228,18 +1238,12 @@ fn cmp( | ... | @@ -1228,18 +1238,12 @@ fn cmp( |
| 1228 | return self.wip.icmp(cond, lhs, rhs, ""); | 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 | fn lowerBlock( | 1241 | fn lowerBlock( |
| 1237 | self: *FuncGen, | 1242 | self: *FuncGen, |
| 1238 | inst: Air.Inst.Index, | 1243 | inst: Air.Inst.Index, |
| 1239 | maybe_inline_func: ?InternPool.Index, | 1244 | maybe_inline_func: ?InternPool.Index, |
| 1240 | body: []const Air.Inst.Index, | 1245 | body: []const Air.Inst.Index, |
| 1241 | ) !Builder.Value { | 1246 | ) TodoError!Builder.Value { |
| 1242 | const o = self.object; | | |
| 1243 | const pt = self.pt; | 1247 | const pt = self.pt; |
| 1244 | const zcu = pt.zcu; | 1248 | const zcu = pt.zcu; |
| 1245 | const inst_ty = self.typeOfIndex(inst); | 1249 | const inst_ty = self.typeOfIndex(inst); |
| ... | @@ -1267,7 +1271,7 @@ fn lowerBlock( | ... | @@ -1267,7 +1271,7 @@ fn lowerBlock( |
| 1267 | | 1271 | |
| 1268 | // Create a phi node only if the block returns a value. | 1272 | // Create a phi node only if the block returns a value. |
| 1269 | if (have_block_result) { | 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 | const llvm_ty: Builder.Type = ty: { | 1275 | const llvm_ty: Builder.Type = ty: { |
| 1272 | // If the zig tag type is a function, this represents an actual function body; not | 1276 | // If the zig tag type is a function, this represents an actual function body; not |
| 1273 | // a pointer to it. LLVM IR allows the call instruction to use function bodies instead | 1277 | // a pointer to it. LLVM IR allows the call instruction to use function bodies instead |
| ... | @@ -1289,7 +1293,7 @@ fn lowerBlock( | ... | @@ -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 | const zcu = self.pt.zcu; | 1297 | const zcu = self.pt.zcu; |
| 1294 | const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br; | 1298 | const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 1295 | const block = self.blocks.get(branch.block_inst).?; | 1299 | const block = self.blocks.get(branch.block_inst).?; |
| ... | @@ -1306,7 +1310,7 @@ fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void { | ... | @@ -1306,7 +1310,7 @@ fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1306 | _ = try self.wip.br(block.parent_bb); | 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 | const repeat = self.air.instructions.items(.data)[@intFromEnum(inst)].repeat; | 1314 | const repeat = self.air.instructions.items(.data)[@intFromEnum(inst)].repeat; |
| 1311 | const loop_bb = self.loops.get(repeat.loop_inst).?; | 1315 | const loop_bb = self.loops.get(repeat.loop_inst).?; |
| 1312 | loop_bb.ptr(&self.wip).incoming += 1; | 1316 | loop_bb.ptr(&self.wip).incoming += 1; |
| ... | @@ -1318,7 +1322,7 @@ fn lowerSwitchDispatch( | ... | @@ -1318,7 +1322,7 @@ fn lowerSwitchDispatch( |
| 1318 | switch_inst: Air.Inst.Index, | 1322 | switch_inst: Air.Inst.Index, |
| 1319 | cond_ref: Air.Inst.Ref, | 1323 | cond_ref: Air.Inst.Ref, |
| 1320 | dispatch_info: SwitchDispatchInfo, | 1324 | dispatch_info: SwitchDispatchInfo, |
| 1321 | ) !void { | 1325 | ) Allocator.Error!void { |
| 1322 | const o = self.object; | 1326 | const o = self.object; |
| 1323 | const pt = self.pt; | 1327 | const pt = self.pt; |
| 1324 | const zcu = pt.zcu; | 1328 | const zcu = pt.zcu; |
| ... | @@ -1384,7 +1388,7 @@ fn lowerSwitchDispatch( | ... | @@ -1384,7 +1388,7 @@ fn lowerSwitchDispatch( |
| 1384 | const table_index = try self.wip.conv( | 1388 | const table_index = try self.wip.conv( |
| 1385 | .unsigned, | 1389 | .unsigned, |
| 1386 | try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""), | 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 | const target_ptr_ptr = try self.ptraddScaled( | 1394 | const target_ptr_ptr = try self.ptraddScaled( |
| ... | @@ -1409,7 +1413,7 @@ fn lowerSwitchDispatch( | ... | @@ -1409,7 +1413,7 @@ fn lowerSwitchDispatch( |
| 1409 | // The switch prongs will correspond to our scalar cases. Ranges will | 1413 | // The switch prongs will correspond to our scalar cases. Ranges will |
| 1410 | // be handled by conditional branches in the `else` prong. | 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 | const cond_int = if (cond.typeOfWip(&self.wip).isPointer(&o.builder)) | 1417 | const cond_int = if (cond.typeOfWip(&self.wip).isPointer(&o.builder)) |
| 1414 | try self.wip.cast(.ptrtoint, cond, llvm_usize, "") | 1418 | try self.wip.cast(.ptrtoint, cond, llvm_usize, "") |
| 1415 | else | 1419 | else |
| ... | @@ -1501,13 +1505,13 @@ fn lowerSwitchDispatch( | ... | @@ -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 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; | 1509 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 1506 | const dispatch_info = self.switch_dispatch_info.get(br.block_inst).?; | 1510 | const dispatch_info = self.switch_dispatch_info.get(br.block_inst).?; |
| 1507 | return self.lowerSwitchDispatch(br.block_inst, br.operand, dispatch_info); | 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 | const cond_br = self.air.unwrapCondBr(inst); | 1515 | const cond_br = self.air.unwrapCondBr(inst); |
| 1512 | const cond = try self.resolveInst(cond_br.condition); | 1516 | const cond = try self.resolveInst(cond_br.condition); |
| 1513 | const then_body = cond_br.then_body; | 1517 | const then_body = cond_br.then_body; |
| ... | @@ -1567,7 +1571,7 @@ fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void { | ... | @@ -1567,7 +1571,7 @@ fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1567 | // No need to reset the insert cursor since this instruction is noreturn. | 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 | const unwrapped_try = self.air.unwrapTry(inst); | 1575 | const unwrapped_try = self.air.unwrapTry(inst); |
| 1572 | const err_union = try self.resolveInst(unwrapped_try.error_union); | 1576 | const err_union = try self.resolveInst(unwrapped_try.error_union); |
| 1573 | const body = unwrapped_try.else_body; | 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,7 +1580,7 @@ fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { |
| 1576 | return lowerTry(self, err_union, body, err_union_ty, false, .none, is_unused, err_cold); | 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 | const zcu = self.pt.zcu; | 1584 | const zcu = self.pt.zcu; |
| 1581 | const unwrapped_try = self.air.unwrapTryPtr(inst); | 1585 | const unwrapped_try = self.air.unwrapTryPtr(inst); |
| 1582 | const err_union_ptr = try self.resolveInst(unwrapped_try.error_union_ptr); | 1586 | const err_union_ptr = try self.resolveInst(unwrapped_try.error_union_ptr); |
| ... | @@ -1599,13 +1603,13 @@ fn lowerTry( | ... | @@ -1599,13 +1603,13 @@ fn lowerTry( |
| 1599 | operand_ptr_align: InternPool.Alignment, | 1603 | operand_ptr_align: InternPool.Alignment, |
| 1600 | is_unused: bool, | 1604 | is_unused: bool, |
| 1601 | err_cold: bool, | 1605 | err_cold: bool, |
| 1602 | ) !Builder.Value { | 1606 | ) TodoError!Builder.Value { |
| 1603 | const o = fg.object; | 1607 | const o = fg.object; |
| 1604 | const pt = fg.pt; | 1608 | const pt = fg.pt; |
| 1605 | const zcu = pt.zcu; | 1609 | const zcu = pt.zcu; |
| 1606 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 1610 | const payload_ty = err_union_ty.errorUnionPayload(zcu); |
| 1607 | const payload_has_bits = payload_ty.hasRuntimeBits(zcu); | 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 | const err_set_align: InternPool.Alignment, const payload_align: InternPool.Alignment = if (operand_is_ptr) .{ | 1614 | const err_set_align: InternPool.Alignment, const payload_align: InternPool.Alignment = if (operand_is_ptr) .{ |
| 1611 | operand_ptr_align.minStrict(Type.anyerror.abiAlignment(zcu)), | 1615 | operand_ptr_align.minStrict(Type.anyerror.abiAlignment(zcu)), |
| ... | @@ -1657,11 +1661,11 @@ fn lowerTry( | ... | @@ -1657,11 +1661,11 @@ fn lowerTry( |
| 1657 | } else if (isByRef(payload_ty, zcu)) { | 1661 | } else if (isByRef(payload_ty, zcu)) { |
| 1658 | return fg.loadByRef(payload_ptr, payload_ty, payload_align.toLlvm(), .normal); | 1662 | return fg.loadByRef(payload_ptr, payload_ty, payload_align.toLlvm(), .normal); |
| 1659 | } else { | 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 | const o = self.object; | 1669 | const o = self.object; |
| 1666 | const pt = self.pt; | 1670 | const pt = self.pt; |
| 1667 | const zcu = pt.zcu; | 1671 | const zcu = pt.zcu; |
| ... | @@ -1909,7 +1913,7 @@ fn switchCaseItemRange(self: *FuncGen, switch_br: Air.UnwrappedSwitch) ?[2]Value | ... | @@ -1909,7 +1913,7 @@ fn switchCaseItemRange(self: *FuncGen, switch_br: Air.UnwrappedSwitch) ?[2]Value |
| 1909 | return .{ min.?, max.? }; | 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 | const block = self.air.unwrapBlock(inst); | 1917 | const block = self.air.unwrapBlock(inst); |
| 1914 | const body = block.body; | 1918 | const body = block.body; |
| 1915 | const loop_block = try self.wip.block(1, "Loop"); // `airRepeat` will increment incoming each time | 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,21 +1926,21 @@ fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 1922 | try self.genBodyDebugScope(null, body, .none); | 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 | const o = self.object; | 1930 | const o = self.object; |
| 1927 | const pt = self.pt; | 1931 | const pt = self.pt; |
| 1928 | const zcu = pt.zcu; | 1932 | const zcu = pt.zcu; |
| 1929 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 1933 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1930 | const operand_ty = self.typeOf(ty_op.operand); | 1934 | const operand_ty = self.typeOf(ty_op.operand); |
| 1931 | const array_ty = operand_ty.childType(zcu); | 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 | const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu)); | 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 | const operand = try self.resolveInst(ty_op.operand); | 1939 | const operand = try self.resolveInst(ty_op.operand); |
| 1936 | return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, ""); | 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 | const o = self.object; | 1944 | const o = self.object; |
| 1941 | const pt = self.pt; | 1945 | const pt = self.pt; |
| 1942 | const zcu = pt.zcu; | 1946 | const zcu = pt.zcu; |
| ... | @@ -1949,7 +1953,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -1949,7 +1953,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1949 | | 1953 | |
| 1950 | const dest_ty = self.typeOfIndex(inst); | 1954 | const dest_ty = self.typeOfIndex(inst); |
| 1951 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 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 | const target = zcu.getTarget(); | 1957 | const target = zcu.getTarget(); |
| 1954 | | 1958 | |
| 1955 | if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv( | 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,7 +1991,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 1987 | extended = try self.wip.cast(.bitcast, extended, param_type, ""); | 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 | return self.wip.call( | 1995 | return self.wip.call( |
| 1992 | .normal, | 1996 | .normal, |
| 1993 | .ccc, | 1997 | .ccc, |
| ... | @@ -2003,7 +2007,7 @@ fn airIntFromFloat( | ... | @@ -2003,7 +2007,7 @@ fn airIntFromFloat( |
| 2003 | self: *FuncGen, | 2007 | self: *FuncGen, |
| 2004 | inst: Air.Inst.Index, | 2008 | inst: Air.Inst.Index, |
| 2005 | fast: Builder.FastMathKind, | 2009 | fast: Builder.FastMathKind, |
| 2006 | ) !Builder.Value { | 2010 | ) TodoError!Builder.Value { |
| 2007 | _ = fast; | 2011 | _ = fast; |
| 2008 | | 2012 | |
| 2009 | const o = self.object; | 2013 | const o = self.object; |
| ... | @@ -2018,7 +2022,7 @@ fn airIntFromFloat( | ... | @@ -2018,7 +2022,7 @@ fn airIntFromFloat( |
| 2018 | | 2022 | |
| 2019 | const dest_ty = self.typeOfIndex(inst); | 2023 | const dest_ty = self.typeOfIndex(inst); |
| 2020 | const dest_scalar_ty = dest_ty.scalarType(zcu); | 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 | if (intrinsicsAllowed(operand_scalar_ty, target)) { | 2027 | if (intrinsicsAllowed(operand_scalar_ty, target)) { |
| 2024 | // TODO set fast math flag | 2028 | // TODO set fast math flag |
| ... | @@ -2052,8 +2056,8 @@ fn airIntFromFloat( | ... | @@ -2052,8 +2056,8 @@ fn airIntFromFloat( |
| 2052 | compiler_rt_dest_abbrev, | 2056 | compiler_rt_dest_abbrev, |
| 2053 | }); | 2057 | }); |
| 2054 | | 2058 | |
| 2055 | const operand_llvm_ty = try o.lowerType(pt, operand_ty); | 2059 | const operand_llvm_ty = try self.lowerType(operand_ty); |
| 2056 | const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty); | 2060 | const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty); |
| 2057 | var result = try self.wip.call( | 2061 | var result = try self.wip.call( |
| 2058 | .normal, | 2062 | .normal, |
| 2059 | .ccc, | 2063 | .ccc, |
| ... | @@ -2078,7 +2082,7 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator. | ... | @@ -2078,7 +2082,7 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator. |
| 2078 | const o = fg.object; | 2082 | const o = fg.object; |
| 2079 | const pt = fg.pt; | 2083 | const pt = fg.pt; |
| 2080 | const zcu = pt.zcu; | 2084 | const zcu = pt.zcu; |
| 2081 | const llvm_usize = try o.lowerType(pt, Type.usize); | 2085 | const llvm_usize = try fg.lowerType(.usize); |
| 2082 | switch (ty.ptrSize(zcu)) { | 2086 | switch (ty.ptrSize(zcu)) { |
| 2083 | .slice => { | 2087 | .slice => { |
| 2084 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); | 2088 | const len = try fg.wip.extractValue(ptr, &.{1}, ""); |
| ... | @@ -2098,20 +2102,20 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator. | ... | @@ -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 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2106 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2103 | const operand = try self.resolveInst(ty_op.operand); | 2107 | const operand = try self.resolveInst(ty_op.operand); |
| 2104 | return self.wip.extractValue(operand, &.{index}, ""); | 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 | const zcu = self.pt.zcu; | 2112 | const zcu = self.pt.zcu; |
| 2109 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2113 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2110 | const slice_ptr = try self.resolveInst(ty_op.operand); | 2114 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 2111 | return self.ptraddConst(slice_ptr, index * Type.usize.abiSize(zcu)); | 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 | const pt = self.pt; | 2119 | const pt = self.pt; |
| 2116 | const zcu = pt.zcu; | 2120 | const zcu = pt.zcu; |
| 2117 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,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 | const pt = self.pt; | 2141 | const pt = self.pt; |
| 2138 | const zcu = pt.zcu; | 2142 | const zcu = pt.zcu; |
| 2139 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 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,7 +2150,7 @@ fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2146 | return self.ptraddScaled(base_ptr, index, slice_ty.childType(zcu).abiSize(zcu)); | 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 | const pt = self.pt; | 2154 | const pt = self.pt; |
| 2151 | const zcu = pt.zcu; | 2155 | const zcu = pt.zcu; |
| 2152 | | 2156 | |
| ... | @@ -2169,7 +2173,7 @@ fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2169,7 +2173,7 @@ fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2169 | return self.wip.extractElement(array_llvm_val, rhs, ""); | 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 | const pt = self.pt; | 2177 | const pt = self.pt; |
| 2174 | const zcu = pt.zcu; | 2178 | const zcu = pt.zcu; |
| 2175 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,7 +2193,7 @@ fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2189 | return self.load(ptr, ptr_ty); | 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 | const pt = self.pt; | 2197 | const pt = self.pt; |
| 2194 | const zcu = pt.zcu; | 2198 | const zcu = pt.zcu; |
| 2195 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 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,7 +2211,7 @@ fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2207 | return self.ptraddScaled(base_ptr, rhs, elem_ty.abiSize(zcu)); | 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 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2215 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2212 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; | 2216 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 2213 | const struct_ptr = try self.resolveInst(struct_field.struct_operand); | 2217 | const struct_ptr = try self.resolveInst(struct_field.struct_operand); |
| ... | @@ -2219,14 +2223,14 @@ fn airStructFieldPtrIndex( | ... | @@ -2219,14 +2223,14 @@ fn airStructFieldPtrIndex( |
| 2219 | self: *FuncGen, | 2223 | self: *FuncGen, |
| 2220 | inst: Air.Inst.Index, | 2224 | inst: Air.Inst.Index, |
| 2221 | field_index: u32, | 2225 | field_index: u32, |
| 2222 | ) !Builder.Value { | 2226 | ) Allocator.Error!Builder.Value { |
| 2223 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2227 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2224 | const struct_ptr = try self.resolveInst(ty_op.operand); | 2228 | const struct_ptr = try self.resolveInst(ty_op.operand); |
| 2225 | const struct_ptr_ty = self.typeOf(ty_op.operand); | 2229 | const struct_ptr_ty = self.typeOf(ty_op.operand); |
| 2226 | return self.fieldPtr(struct_ptr, struct_ptr_ty, field_index); | 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 | const o = self.object; | 2234 | const o = self.object; |
| 2231 | const pt = self.pt; | 2235 | const pt = self.pt; |
| 2232 | const zcu = pt.zcu; | 2236 | const zcu = pt.zcu; |
| ... | @@ -2267,7 +2271,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2267,7 +2271,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2267 | }, | 2271 | }, |
| 2268 | .float => { | 2272 | .float => { |
| 2269 | // bitcast int->float | 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,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 | const o = self.object; | 2300 | const o = self.object; |
| 2297 | const pt = self.pt; | 2301 | const pt = self.pt; |
| 2298 | const zcu = pt.zcu; | 2302 | const zcu = pt.zcu; |
| ... | @@ -2305,8 +2309,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2305,8 +2309,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2305 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); | 2309 | const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu); |
| 2306 | if (field_offset == 0) return field_ptr; | 2310 | if (field_offset == 0) return field_ptr; |
| 2307 | | 2311 | |
| 2308 | const res_ty = try o.lowerType(pt, ty_pl.ty.toType()); | 2312 | const res_ty = try self.lowerType(ty_pl.ty.toType()); |
| 2309 | const llvm_usize = try o.lowerType(pt, Type.usize); | 2313 | const llvm_usize = try self.lowerType(Type.usize); |
| 2310 | | 2314 | |
| 2311 | const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, ""); | 2315 | const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, ""); |
| 2312 | const base_ptr_int = try self.wip.bin( | 2316 | const base_ptr_int = try self.wip.bin( |
| ... | @@ -2318,19 +2322,19 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2318,19 +2322,19 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2318 | return self.wip.cast(.inttoptr, base_ptr_int, res_ty, ""); | 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 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2326 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2323 | const operand = try self.resolveInst(ty_op.operand); | 2327 | const operand = try self.resolveInst(ty_op.operand); |
| 2324 | | 2328 | |
| 2325 | return self.wip.not(operand, ""); | 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 | _ = inst; | 2333 | _ = inst; |
| 2330 | _ = try self.wip.@"unreachable"(); | 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 | const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; | 2338 | const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 2335 | self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1); | 2339 | self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1); |
| 2336 | self.prev_dbg_column = @intCast(dbg_stmt.column + 1); | 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,19 +2349,13 @@ fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2345 | return .none; | 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 | _ = self; | 2353 | _ = self; |
| 2350 | _ = inst; | 2354 | _ = inst; |
| 2351 | return .none; | 2355 | return .none; |
| 2352 | } | 2356 | } |
| 2353 | | 2357 | |
| 2354 | fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 2358 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!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 { | | |
| 2361 | const o = self.object; | 2359 | const o = self.object; |
| 2362 | const pt = self.pt; | 2360 | const pt = self.pt; |
| 2363 | const zcu = pt.zcu; | 2361 | const zcu = pt.zcu; |
| ... | @@ -2390,7 +2388,7 @@ fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2390,7 +2388,7 @@ fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2390 | return .none; | 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 | const o = self.object; | 2392 | const o = self.object; |
| 2395 | const pt = self.pt; | 2393 | const pt = self.pt; |
| 2396 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 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,7 +2466,7 @@ fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Val |
| 2468 | return .none; | 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 | // Eventually, the Zig compiler needs to be reworked to have inline | 2470 | // Eventually, the Zig compiler needs to be reworked to have inline |
| 2473 | // assembly go through the same parsing code regardless of backend, and | 2471 | // assembly go through the same parsing code regardless of backend, and |
| 2474 | // have LLVM-flavored inline assembly be *output* from that assembler. | 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,7 +2528,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2530 | const output_inst = try self.resolveInst(output.operand); | 2528 | const output_inst = try self.resolveInst(output.operand); |
| 2531 | const output_ty = self.typeOf(output.operand); | 2529 | const output_ty = self.typeOf(output.operand); |
| 2532 | assert(output_ty.zigTypeTag(zcu) == .pointer); | 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 | switch (constraint[0]) { | 2533 | switch (constraint[0]) { |
| 2536 | '=' => {}, | 2534 | '=' => {}, |
| ... | @@ -2568,7 +2566,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2568,7 +2566,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2568 | llvm_ret_indirect[output.index] = false; | 2566 | llvm_ret_indirect[output.index] = false; |
| 2569 | | 2567 | |
| 2570 | const ret_ty = self.typeOfIndex(inst); | 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 | llvm_ret_i += 1; | 2570 | llvm_ret_i += 1; |
| 2573 | } | 2571 | } |
| 2574 | | 2572 | |
| ... | @@ -2607,7 +2605,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2607,7 +2605,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2607 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); | 2605 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip); |
| 2608 | } else { | 2606 | } else { |
| 2609 | const alignment = arg_ty.abiAlignment(zcu).toLlvm(); | 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 | const load_inst = | 2609 | const load_inst = |
| 2612 | try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); | 2610 | try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, ""); |
| 2613 | llvm_param_values[llvm_param_i] = load_inst; | 2611 | llvm_param_values[llvm_param_i] = load_inst; |
| ... | @@ -2648,7 +2646,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2648,7 +2646,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2648 | llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: { | 2646 | llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: { |
| 2649 | if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu)); | 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 | } else .none; | 2650 | } else .none; |
| 2653 | | 2651 | |
| 2654 | llvm_param_i += 1; | 2652 | llvm_param_i += 1; |
| ... | @@ -2662,7 +2660,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -2662,7 +2660,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 2662 | if (constraint[0] != '+') continue; | 2660 | if (constraint[0] != '+') continue; |
| 2663 | | 2661 | |
| 2664 | const rw_ty = self.typeOf(output.operand); | 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 | if (llvm_ret_indirect[output.index]) { | 2664 | if (llvm_ret_indirect[output.index]) { |
| 2667 | llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index]; | 2665 | llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index]; |
| 2668 | llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip); | 2666 | llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip); |
| ... | @@ -2855,7 +2853,7 @@ fn airIsNonNull( | ... | @@ -2855,7 +2853,7 @@ fn airIsNonNull( |
| 2855 | inst: Air.Inst.Index, | 2853 | inst: Air.Inst.Index, |
| 2856 | operand_is_ptr: bool, | 2854 | operand_is_ptr: bool, |
| 2857 | cond: Builder.IntegerCondition, | 2855 | cond: Builder.IntegerCondition, |
| 2858 | ) !Builder.Value { | 2856 | ) Allocator.Error!Builder.Value { |
| 2859 | const o = self.object; | 2857 | const o = self.object; |
| 2860 | const pt = self.pt; | 2858 | const pt = self.pt; |
| 2861 | const zcu = pt.zcu; | 2859 | const zcu = pt.zcu; |
| ... | @@ -2863,7 +2861,7 @@ fn airIsNonNull( | ... | @@ -2863,7 +2861,7 @@ fn airIsNonNull( |
| 2863 | const operand = try self.resolveInst(un_op); | 2861 | const operand = try self.resolveInst(un_op); |
| 2864 | const operand_ty = self.typeOf(un_op); | 2862 | const operand_ty = self.typeOf(un_op); |
| 2865 | const optional_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | 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 | const payload_ty = optional_ty.optionalChild(zcu); | 2865 | const payload_ty = optional_ty.optionalChild(zcu); |
| 2868 | | 2866 | |
| 2869 | const access_kind: Builder.MemoryAccessKind = | 2867 | const access_kind: Builder.MemoryAccessKind = |
| ... | @@ -2905,7 +2903,7 @@ fn airIsErr( | ... | @@ -2905,7 +2903,7 @@ fn airIsErr( |
| 2905 | inst: Air.Inst.Index, | 2903 | inst: Air.Inst.Index, |
| 2906 | cond: Builder.IntegerCondition, | 2904 | cond: Builder.IntegerCondition, |
| 2907 | operand_is_ptr: bool, | 2905 | operand_is_ptr: bool, |
| 2908 | ) !Builder.Value { | 2906 | ) Allocator.Error!Builder.Value { |
| 2909 | const o = self.object; | 2907 | const o = self.object; |
| 2910 | const pt = self.pt; | 2908 | const pt = self.pt; |
| 2911 | const zcu = pt.zcu; | 2909 | const zcu = pt.zcu; |
| ... | @@ -2914,7 +2912,7 @@ fn airIsErr( | ... | @@ -2914,7 +2912,7 @@ fn airIsErr( |
| 2914 | const operand_ty = self.typeOf(un_op); | 2912 | const operand_ty = self.typeOf(un_op); |
| 2915 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | 2913 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 2916 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 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 | const zero = try o.builder.intValue(error_type, 0); | 2916 | const zero = try o.builder.intValue(error_type, 0); |
| 2919 | | 2917 | |
| 2920 | const access_kind: Builder.MemoryAccessKind = | 2918 | const access_kind: Builder.MemoryAccessKind = |
| ... | @@ -2933,7 +2931,7 @@ fn airIsErr( | ... | @@ -2933,7 +2931,7 @@ fn airIsErr( |
| 2933 | | 2931 | |
| 2934 | if (!payload_ty.hasRuntimeBits(zcu)) { | 2932 | if (!payload_ty.hasRuntimeBits(zcu)) { |
| 2935 | const loaded = if (operand_is_ptr) | 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 | else | 2935 | else |
| 2938 | operand; | 2936 | operand; |
| 2939 | return self.wip.icmp(cond, loaded, zero, ""); | 2937 | return self.wip.icmp(cond, loaded, zero, ""); |
| ... | @@ -2957,7 +2955,7 @@ fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!B | ... | @@ -2957,7 +2955,7 @@ fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!B |
| 2957 | return operand; | 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 | comptime assert(optional_layout_version == 3); | 2959 | comptime assert(optional_layout_version == 3); |
| 2962 | | 2960 | |
| 2963 | const o = self.object; | 2961 | const o = self.object; |
| ... | @@ -3002,7 +3000,7 @@ fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value | ... | @@ -3002,7 +3000,7 @@ fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value |
| 3002 | return operand; // payload is at offset 0 | 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 | const pt = self.pt; | 3004 | const pt = self.pt; |
| 3007 | const zcu = pt.zcu; | 3005 | const zcu = pt.zcu; |
| 3008 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 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,8 +3017,7 @@ fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3019 | return self.optPayloadHandle(operand, optional_ty, false); | 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 { | 3020 | fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool) Allocator.Error!Builder.Value { |
| 3023 | const o = self.object; | | |
| 3024 | const pt = self.pt; | 3021 | const pt = self.pt; |
| 3025 | const zcu = pt.zcu; | 3022 | const zcu = pt.zcu; |
| 3026 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 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,7 +3039,7 @@ fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool |
| 3042 | if (isByRef(payload_ty, zcu)) { | 3039 | if (isByRef(payload_ty, zcu)) { |
| 3043 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); | 3040 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); |
| 3044 | } else { | 3041 | } else { |
| 3045 | const payload_llvm_ty = try o.lowerType(pt, payload_ty); | 3042 | const payload_llvm_ty = try self.lowerType(payload_ty); |
| 3046 | return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, ""); | 3043 | return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, ""); |
| 3047 | } | 3044 | } |
| 3048 | } | 3045 | } |
| ... | @@ -3051,14 +3048,14 @@ fn airErrUnionErr( | ... | @@ -3051,14 +3048,14 @@ fn airErrUnionErr( |
| 3051 | self: *FuncGen, | 3048 | self: *FuncGen, |
| 3052 | inst: Air.Inst.Index, | 3049 | inst: Air.Inst.Index, |
| 3053 | operand_is_ptr: bool, | 3050 | operand_is_ptr: bool, |
| 3054 | ) !Builder.Value { | 3051 | ) Allocator.Error!Builder.Value { |
| 3055 | const o = self.object; | 3052 | const o = self.object; |
| 3056 | const pt = self.pt; | 3053 | const pt = self.pt; |
| 3057 | const zcu = pt.zcu; | 3054 | const zcu = pt.zcu; |
| 3058 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3055 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3059 | const operand = try self.resolveInst(ty_op.operand); | 3056 | const operand = try self.resolveInst(ty_op.operand); |
| 3060 | const operand_ty = self.typeOf(ty_op.operand); | 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 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; | 3059 | const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty; |
| 3063 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | 3060 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 3064 | if (operand_is_ptr) { | 3061 | if (operand_is_ptr) { |
| ... | @@ -3094,7 +3091,7 @@ fn airErrUnionErr( | ... | @@ -3094,7 +3091,7 @@ fn airErrUnionErr( |
| 3094 | return self.wip.load(access_kind, error_type, err_field_ptr, err_align.toLlvm(), ""); | 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 | const o = self.object; | 3095 | const o = self.object; |
| 3099 | const pt = self.pt; | 3096 | const pt = self.pt; |
| 3100 | const zcu = pt.zcu; | 3097 | const zcu = pt.zcu; |
| ... | @@ -3105,7 +3102,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value | ... | @@ -3105,7 +3102,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value |
| 3105 | const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu); | 3102 | const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu); |
| 3106 | | 3103 | |
| 3107 | const payload_ty = err_union_ty.errorUnionPayload(zcu); | 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 | const access_kind: Builder.MemoryAccessKind = | 3107 | const access_kind: Builder.MemoryAccessKind = |
| 3111 | if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | 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,18 +3121,18 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value |
| 3124 | return self.ptraddConst(operand, codegen.errUnionPayloadOffset(payload_ty, zcu)); | 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 | assert(self.err_ret_trace != .none); | 3125 | assert(self.err_ret_trace != .none); |
| 3129 | return self.err_ret_trace; | 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 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 3130 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 3134 | self.err_ret_trace = try self.resolveInst(un_op); | 3131 | self.err_ret_trace = try self.resolveInst(un_op); |
| 3135 | return .none; | 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 | const pt = self.pt; | 3136 | const pt = self.pt; |
| 3140 | const zcu = pt.zcu; | 3137 | const zcu = pt.zcu; |
| 3141 | | 3138 | |
| ... | @@ -3184,7 +3181,7 @@ fn isNextRet( | ... | @@ -3184,7 +3181,7 @@ fn isNextRet( |
| 3184 | return false; | 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 | const o = self.object; | 3185 | const o = self.object; |
| 3189 | const pt = self.pt; | 3186 | const pt = self.pt; |
| 3190 | const zcu = pt.zcu; | 3187 | const zcu = pt.zcu; |
| ... | @@ -3198,7 +3195,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V | ... | @@ -3198,7 +3195,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V |
| 3198 | const optional_ty = self.typeOfIndex(inst); | 3195 | const optional_ty = self.typeOfIndex(inst); |
| 3199 | if (optional_ty.optionalReprIsPayload(zcu)) return operand; | 3196 | if (optional_ty.optionalReprIsPayload(zcu)) return operand; |
| 3200 | assert(isByRef(optional_ty, zcu)); // optionals with runtime bits are by-ref unless `optionalReprIsPayload` | 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 | const optional_ptr = if (self.isNextRet(body_tail)) | 3199 | const optional_ptr = if (self.isNextRet(body_tail)) |
| 3203 | self.ret_ptr | 3200 | self.ret_ptr |
| 3204 | else brk: { | 3201 | else brk: { |
| ... | @@ -3216,7 +3213,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V | ... | @@ -3216,7 +3213,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V |
| 3216 | return optional_ptr; | 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 | const o = self.object; | 3217 | const o = self.object; |
| 3221 | const pt = self.pt; | 3218 | const pt = self.pt; |
| 3222 | const zcu = pt.zcu; | 3219 | const zcu = pt.zcu; |
| ... | @@ -3227,8 +3224,8 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu | ... | @@ -3227,8 +3224,8 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu |
| 3227 | const payload_ty = self.typeOf(ty_op.operand); | 3224 | const payload_ty = self.typeOf(ty_op.operand); |
| 3228 | assert(payload_ty.hasRuntimeBits(zcu)); | 3225 | assert(payload_ty.hasRuntimeBits(zcu)); |
| 3229 | assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref | 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); | 3227 | const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0); |
| 3231 | const err_un_llvm_ty = try o.lowerType(pt, err_un_ty); | 3228 | const err_un_llvm_ty = try self.lowerType(err_un_ty); |
| 3232 | | 3229 | |
| 3233 | const result_ptr = if (self.isNextRet(body_tail)) | 3230 | const result_ptr = if (self.isNextRet(body_tail)) |
| 3234 | self.ret_ptr | 3231 | self.ret_ptr |
| ... | @@ -3247,8 +3244,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu | ... | @@ -3247,8 +3244,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu |
| 3247 | return result_ptr; | 3244 | return result_ptr; |
| 3248 | } | 3245 | } |
| 3249 | | 3246 | |
| 3250 | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 3247 | fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3251 | const o = self.object; | | |
| 3252 | const pt = self.pt; | 3248 | const pt = self.pt; |
| 3253 | const zcu = pt.zcu; | 3249 | const zcu = pt.zcu; |
| 3254 | const inst = body_tail[0]; | 3250 | const inst = body_tail[0]; |
| ... | @@ -3258,7 +3254,7 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde | ... | @@ -3258,7 +3254,7 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde |
| 3258 | const operand = try self.resolveInst(ty_op.operand); | 3254 | const operand = try self.resolveInst(ty_op.operand); |
| 3259 | if (!payload_ty.hasRuntimeBits(zcu)) return operand; | 3255 | if (!payload_ty.hasRuntimeBits(zcu)) return operand; |
| 3260 | assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref | 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 | const result_ptr = if (self.isNextRet(body_tail)) | 3259 | const result_ptr = if (self.isNextRet(body_tail)) |
| 3264 | self.ret_ptr | 3260 | self.ret_ptr |
| ... | @@ -3279,29 +3275,27 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde | ... | @@ -3279,29 +3275,27 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde |
| 3279 | return result_ptr; | 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 | const o = self.object; | 3279 | const o = self.object; |
| 3284 | const pt = self.pt; | | |
| 3285 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 3280 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 3286 | const index = pl_op.payload; | 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 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{ | 3283 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{ |
| 3289 | try o.builder.intValue(.i32, index), | 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 | const o = self.object; | 3289 | const o = self.object; |
| 3295 | const pt = self.pt; | | |
| 3296 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 3290 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 3297 | const index = pl_op.payload; | 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 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{ | 3293 | return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{ |
| 3300 | try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand), | 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 | const o = fg.object; | 3299 | const o = fg.object; |
| 3306 | const pt = fg.pt; | 3300 | const pt = fg.pt; |
| 3307 | const ty_nav = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav; | 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,8 +3303,7 @@ fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3309 | return llvm_ptr_const.toValue(); | 3303 | return llvm_ptr_const.toValue(); |
| 3310 | } | 3304 | } |
| 3311 | | 3305 | |
| 3312 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 3306 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3313 | const o = self.object; | | |
| 3314 | const pt = self.pt; | 3307 | const pt = self.pt; |
| 3315 | const zcu = pt.zcu; | 3308 | const zcu = pt.zcu; |
| 3316 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,14 +3317,13 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3324 | .normal, | 3317 | .normal, |
| 3325 | .none, | 3318 | .none, |
| 3326 | if (scalar_ty.isSignedInt(zcu)) .smin else .umin, | 3319 | if (scalar_ty.isSignedInt(zcu)) .smin else .umin, |
| 3327 | &.{try o.lowerType(pt, inst_ty)}, | 3320 | &.{try self.lowerType(inst_ty)}, |
| 3328 | &.{ lhs, rhs }, | 3321 | &.{ lhs, rhs }, |
| 3329 | "", | 3322 | "", |
| 3330 | ); | 3323 | ); |
| 3331 | } | 3324 | } |
| 3332 | | 3325 | |
| 3333 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 3326 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3334 | const o = self.object; | | |
| 3335 | const pt = self.pt; | 3327 | const pt = self.pt; |
| 3336 | const zcu = pt.zcu; | 3328 | const zcu = pt.zcu; |
| 3337 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,24 +3337,22 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3345 | .normal, | 3337 | .normal, |
| 3346 | .none, | 3338 | .none, |
| 3347 | if (scalar_ty.isSignedInt(zcu)) .smax else .umax, | 3339 | if (scalar_ty.isSignedInt(zcu)) .smax else .umax, |
| 3348 | &.{try o.lowerType(pt, inst_ty)}, | 3340 | &.{try self.lowerType(inst_ty)}, |
| 3349 | &.{ lhs, rhs }, | 3341 | &.{ lhs, rhs }, |
| 3350 | "", | 3342 | "", |
| 3351 | ); | 3343 | ); |
| 3352 | } | 3344 | } |
| 3353 | | 3345 | |
| 3354 | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 3346 | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3355 | const o = self.object; | | |
| 3356 | const pt = self.pt; | | |
| 3357 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3347 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3358 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3348 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3359 | const ptr = try self.resolveInst(bin_op.lhs); | 3349 | const ptr = try self.resolveInst(bin_op.lhs); |
| 3360 | const len = try self.resolveInst(bin_op.rhs); | 3350 | const len = try self.resolveInst(bin_op.rhs); |
| 3361 | const inst_ty = self.typeOfIndex(inst); | 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 | const zcu = self.pt.zcu; | 3356 | const zcu = self.pt.zcu; |
| 3367 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3357 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3368 | const lhs = try self.resolveInst(bin_op.lhs); | 3358 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | @@ -3379,7 +3369,7 @@ fn airSafeArithmetic( | ... | @@ -3379,7 +3369,7 @@ fn airSafeArithmetic( |
| 3379 | inst: Air.Inst.Index, | 3369 | inst: Air.Inst.Index, |
| 3380 | signed_intrinsic: Builder.Intrinsic, | 3370 | signed_intrinsic: Builder.Intrinsic, |
| 3381 | unsigned_intrinsic: Builder.Intrinsic, | 3371 | unsigned_intrinsic: Builder.Intrinsic, |
| 3382 | ) !Builder.Value { | 3372 | ) Allocator.Error!Builder.Value { |
| 3383 | const o = fg.object; | 3373 | const o = fg.object; |
| 3384 | const pt = fg.pt; | 3374 | const pt = fg.pt; |
| 3385 | const zcu = pt.zcu; | 3375 | const zcu = pt.zcu; |
| ... | @@ -3391,7 +3381,7 @@ fn airSafeArithmetic( | ... | @@ -3391,7 +3381,7 @@ fn airSafeArithmetic( |
| 3391 | const scalar_ty = inst_ty.scalarType(zcu); | 3381 | const scalar_ty = inst_ty.scalarType(zcu); |
| 3392 | | 3382 | |
| 3393 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; | 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 | const results = | 3385 | const results = |
| 3396 | try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, ""); | 3386 | try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, ""); |
| 3397 | | 3387 | |
| ... | @@ -3420,7 +3410,7 @@ fn airSafeArithmetic( | ... | @@ -3420,7 +3410,7 @@ fn airSafeArithmetic( |
| 3420 | return fg.wip.extractValue(results, &.{0}, ""); | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3414 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3425 | const lhs = try self.resolveInst(bin_op.lhs); | 3415 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3426 | const rhs = try self.resolveInst(bin_op.rhs); | 3416 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -3428,8 +3418,7 @@ fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -3428,8 +3418,7 @@ fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3428 | return self.wip.bin(.add, lhs, rhs, ""); | 3418 | return self.wip.bin(.add, lhs, rhs, ""); |
| 3429 | } | 3419 | } |
| 3430 | | 3420 | |
| 3431 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 3421 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3432 | const o = self.object; | | |
| 3433 | const pt = self.pt; | 3422 | const pt = self.pt; |
| 3434 | const zcu = pt.zcu; | 3423 | const zcu = pt.zcu; |
| 3435 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,13 +3431,13 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3442 | .normal, | 3431 | .normal, |
| 3443 | .none, | 3432 | .none, |
| 3444 | if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat", | 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 | &.{ lhs, rhs }, | 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 | const zcu = self.pt.zcu; | 3441 | const zcu = self.pt.zcu; |
| 3453 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3442 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3454 | const lhs = try self.resolveInst(bin_op.lhs); | 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,7 +3449,7 @@ fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3460 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"sub nsw" else .@"sub nuw", lhs, rhs, ""); | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3453 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3465 | const lhs = try self.resolveInst(bin_op.lhs); | 3454 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3466 | const rhs = try self.resolveInst(bin_op.rhs); | 3455 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -3468,8 +3457,7 @@ fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -3468,8 +3457,7 @@ fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3468 | return self.wip.bin(.sub, lhs, rhs, ""); | 3457 | return self.wip.bin(.sub, lhs, rhs, ""); |
| 3469 | } | 3458 | } |
| 3470 | | 3459 | |
| 3471 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 3460 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3472 | const o = self.object; | | |
| 3473 | const pt = self.pt; | 3461 | const pt = self.pt; |
| 3474 | const zcu = pt.zcu; | 3462 | const zcu = pt.zcu; |
| 3475 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,13 +3470,13 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3482 | .normal, | 3470 | .normal, |
| 3483 | .none, | 3471 | .none, |
| 3484 | if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat", | 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 | &.{ lhs, rhs }, | 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 | const zcu = self.pt.zcu; | 3480 | const zcu = self.pt.zcu; |
| 3493 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3481 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3494 | const lhs = try self.resolveInst(bin_op.lhs); | 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,7 +3488,7 @@ fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3500 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"mul nsw" else .@"mul nuw", lhs, rhs, ""); | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3492 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3505 | const lhs = try self.resolveInst(bin_op.lhs); | 3493 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3506 | const rhs = try self.resolveInst(bin_op.rhs); | 3494 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -3508,8 +3496,7 @@ fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -3508,8 +3496,7 @@ fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3508 | return self.wip.bin(.mul, lhs, rhs, ""); | 3496 | return self.wip.bin(.mul, lhs, rhs, ""); |
| 3509 | } | 3497 | } |
| 3510 | | 3498 | |
| 3511 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 3499 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 3512 | const o = self.object; | | |
| 3513 | const pt = self.pt; | 3500 | const pt = self.pt; |
| 3514 | const zcu = pt.zcu; | 3501 | const zcu = pt.zcu; |
| 3515 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,13 +3509,13 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3522 | .normal, | 3509 | .normal, |
| 3523 | .none, | 3510 | .none, |
| 3524 | if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat", | 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 | &.{ lhs, rhs, .@"0" }, | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3519 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3533 | const lhs = try self.resolveInst(bin_op.lhs); | 3520 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3534 | const rhs = try self.resolveInst(bin_op.rhs); | 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,7 +3524,7 @@ fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3537 | return self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs }); | 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 | const zcu = self.pt.zcu; | 3528 | const zcu = self.pt.zcu; |
| 3542 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3529 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3543 | const lhs = try self.resolveInst(bin_op.lhs); | 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,7 +3539,7 @@ fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3552 | return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .sdiv else .udiv, lhs, rhs, ""); | 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 | const o = self.object; | 3543 | const o = self.object; |
| 3557 | const pt = self.pt; | 3544 | const pt = self.pt; |
| 3558 | const zcu = pt.zcu; | 3545 | const zcu = pt.zcu; |
| ... | @@ -3567,7 +3554,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) | ... | @@ -3567,7 +3554,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3567 | return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result}); | 3554 | return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result}); |
| 3568 | } | 3555 | } |
| 3569 | if (scalar_ty.isSignedInt(zcu)) { | 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 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; | 3559 | const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb; |
| 3573 | var stack align(@max( | 3560 | var stack align(@max( |
| ... | @@ -3603,7 +3590,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) | ... | @@ -3603,7 +3590,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) |
| 3603 | return self.wip.bin(.udiv, lhs, rhs, ""); | 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 | const zcu = self.pt.zcu; | 3594 | const zcu = self.pt.zcu; |
| 3608 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3595 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3609 | const lhs = try self.resolveInst(bin_op.lhs); | 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,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 | const zcu = self.pt.zcu; | 3611 | const zcu = self.pt.zcu; |
| 3625 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3612 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3626 | const lhs = try self.resolveInst(bin_op.lhs); | 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,7 +3623,7 @@ fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3636 | .urem, lhs, rhs, ""); | 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 | const o = self.object; | 3627 | const o = self.object; |
| 3641 | const pt = self.pt; | 3628 | const pt = self.pt; |
| 3642 | const zcu = pt.zcu; | 3629 | const zcu = pt.zcu; |
| ... | @@ -3644,7 +3631,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui | ... | @@ -3644,7 +3631,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3644 | const lhs = try self.resolveInst(bin_op.lhs); | 3631 | const lhs = try self.resolveInst(bin_op.lhs); |
| 3645 | const rhs = try self.resolveInst(bin_op.rhs); | 3632 | const rhs = try self.resolveInst(bin_op.rhs); |
| 3646 | const inst_ty = self.typeOfIndex(inst); | 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 | const scalar_ty = inst_ty.scalarType(zcu); | 3635 | const scalar_ty = inst_ty.scalarType(zcu); |
| 3649 | | 3636 | |
| 3650 | if (scalar_ty.isRuntimeFloat()) { | 3637 | if (scalar_ty.isRuntimeFloat()) { |
| ... | @@ -3690,7 +3677,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui | ... | @@ -3690,7 +3677,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 3690 | return self.wip.bin(.urem, lhs, rhs, ""); | 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 | const zcu = self.pt.zcu; | 3681 | const zcu = self.pt.zcu; |
| 3695 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3682 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3696 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 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,14 +3692,14 @@ fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3705 | return self.ptraddScaled(ptr, index, elem_ty.abiSize(zcu)); | 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 | const o = self.object; | 3696 | const o = self.object; |
| 3710 | const pt = self.pt; | 3697 | const pt = self.pt; |
| 3711 | const zcu = pt.zcu; | 3698 | const zcu = pt.zcu; |
| 3712 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3699 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3713 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3700 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3714 | const ptr_or_slice = try self.resolveInst(bin_op.lhs); | 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 | const ptr_ty = self.typeOf(bin_op.lhs); | 3703 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3717 | const elem_ty = ptr_ty.indexableElem(zcu); | 3704 | const elem_ty = ptr_ty.indexableElem(zcu); |
| 3718 | const ptr = switch (ptr_ty.ptrSize(zcu)) { | 3705 | const ptr = switch (ptr_ty.ptrSize(zcu)) { |
| ... | @@ -3722,7 +3709,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -3722,7 +3709,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 3722 | const scale_val = try o.builder.intValue(llvm_usize_ty, -@as(i65, elem_ty.abiSize(zcu))); | 3709 | const scale_val = try o.builder.intValue(llvm_usize_ty, -@as(i65, elem_ty.abiSize(zcu))); |
| 3723 | const positive_index = try self.resolveInst(bin_op.rhs); | 3710 | const positive_index = try self.resolveInst(bin_op.rhs); |
| 3724 | const negative_offset = try self.wip.bin(.@"mul nsw", positive_index, scale_val, ""); | 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 | fn airOverflow( | 3715 | fn airOverflow( |
| ... | @@ -3730,8 +3717,7 @@ fn airOverflow( | ... | @@ -3730,8 +3717,7 @@ fn airOverflow( |
| 3730 | inst: Air.Inst.Index, | 3717 | inst: Air.Inst.Index, |
| 3731 | signed_intrinsic: Builder.Intrinsic, | 3718 | signed_intrinsic: Builder.Intrinsic, |
| 3732 | unsigned_intrinsic: Builder.Intrinsic, | 3719 | unsigned_intrinsic: Builder.Intrinsic, |
| 3733 | ) !Builder.Value { | 3720 | ) Allocator.Error!Builder.Value { |
| 3734 | const o = self.object; | | |
| 3735 | const pt = self.pt; | 3721 | const pt = self.pt; |
| 3736 | const zcu = pt.zcu; | 3722 | const zcu = pt.zcu; |
| 3737 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3723 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -3746,8 +3732,8 @@ fn airOverflow( | ... | @@ -3746,8 +3732,8 @@ fn airOverflow( |
| 3746 | assert(isByRef(inst_ty, zcu)); // auto structs are by-ref | 3732 | assert(isByRef(inst_ty, zcu)); // auto structs are by-ref |
| 3747 | | 3733 | |
| 3748 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; | 3734 | const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic; |
| 3749 | const llvm_inst_ty = try o.lowerType(pt, inst_ty); | 3735 | const llvm_inst_ty = try self.lowerType(inst_ty); |
| 3750 | const llvm_lhs_ty = try o.lowerType(pt, lhs_ty); | 3736 | const llvm_lhs_ty = try self.lowerType(lhs_ty); |
| 3751 | const results = | 3737 | const results = |
| 3752 | try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, ""); | 3738 | try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, ""); |
| 3753 | | 3739 | |
| ... | @@ -3778,7 +3764,7 @@ fn buildElementwiseCall( | ... | @@ -3778,7 +3764,7 @@ fn buildElementwiseCall( |
| 3778 | args_vectors: []const Builder.Value, | 3764 | args_vectors: []const Builder.Value, |
| 3779 | result_vector: Builder.Value, | 3765 | result_vector: Builder.Value, |
| 3780 | vector_len: usize, | 3766 | vector_len: usize, |
| 3781 | ) !Builder.Value { | 3767 | ) Allocator.Error!Builder.Value { |
| 3782 | const o = self.object; | 3768 | const o = self.object; |
| 3783 | assert(args_vectors.len <= 3); | 3769 | assert(args_vectors.len <= 3); |
| 3784 | | 3770 | |
| ... | @@ -3805,25 +3791,6 @@ fn buildElementwiseCall( | ... | @@ -3805,25 +3791,6 @@ fn buildElementwiseCall( |
| 3805 | return result; | 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 | /// Creates a floating point comparison by lowering to the appropriate | 3794 | /// Creates a floating point comparison by lowering to the appropriate |
| 3828 | /// hardware instruction or softfloat routine for the target | 3795 | /// hardware instruction or softfloat routine for the target |
| 3829 | fn buildFloatCmp( | 3796 | fn buildFloatCmp( |
| ... | @@ -3832,13 +3799,13 @@ fn buildFloatCmp( | ... | @@ -3832,13 +3799,13 @@ fn buildFloatCmp( |
| 3832 | pred: math.CompareOperator, | 3799 | pred: math.CompareOperator, |
| 3833 | ty: Type, | 3800 | ty: Type, |
| 3834 | params: [2]Builder.Value, | 3801 | params: [2]Builder.Value, |
| 3835 | ) !Builder.Value { | 3802 | ) Allocator.Error!Builder.Value { |
| 3836 | const o = self.object; | 3803 | const o = self.object; |
| 3837 | const pt = self.pt; | 3804 | const pt = self.pt; |
| 3838 | const zcu = pt.zcu; | 3805 | const zcu = pt.zcu; |
| 3839 | const target = zcu.getTarget(); | 3806 | const target = zcu.getTarget(); |
| 3840 | const scalar_ty = ty.scalarType(zcu); | 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 | if (intrinsicsAllowed(scalar_ty, target)) { | 3810 | if (intrinsicsAllowed(scalar_ty, target)) { |
| 3844 | const cond: Builder.FloatCondition = switch (pred) { | 3811 | const cond: Builder.FloatCondition = switch (pred) { |
| ... | @@ -3864,7 +3831,7 @@ fn buildFloatCmp( | ... | @@ -3864,7 +3831,7 @@ fn buildFloatCmp( |
| 3864 | }; | 3831 | }; |
| 3865 | const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev }); | 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 | const int_cond: Builder.IntegerCondition = switch (pred) { | 3836 | const int_cond: Builder.IntegerCondition = switch (pred) { |
| 3870 | .eq => .eq, | 3837 | .eq => .eq, |
| ... | @@ -3939,13 +3906,13 @@ fn buildFloatOp( | ... | @@ -3939,13 +3906,13 @@ fn buildFloatOp( |
| 3939 | ty: Type, | 3906 | ty: Type, |
| 3940 | comptime params_len: usize, | 3907 | comptime params_len: usize, |
| 3941 | params: [params_len]Builder.Value, | 3908 | params: [params_len]Builder.Value, |
| 3942 | ) !Builder.Value { | 3909 | ) Allocator.Error!Builder.Value { |
| 3943 | const o = self.object; | 3910 | const o = self.object; |
| 3944 | const pt = self.pt; | 3911 | const pt = self.pt; |
| 3945 | const zcu = pt.zcu; | 3912 | const zcu = pt.zcu; |
| 3946 | const target = zcu.getTarget(); | 3913 | const target = zcu.getTarget(); |
| 3947 | const scalar_ty = ty.scalarType(zcu); | 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 | if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) { | 3917 | if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) { |
| 3951 | // Some operations are dedicated LLVM instructions, not available as intrinsics | 3918 | // Some operations are dedicated LLVM instructions, not available as intrinsics |
| ... | @@ -4048,7 +4015,7 @@ fn buildFloatOp( | ... | @@ -4048,7 +4015,7 @@ fn buildFloatOp( |
| 4048 | }; | 4015 | }; |
| 4049 | | 4016 | |
| 4050 | const scalar_llvm_ty = llvm_ty.scalarType(&o.builder); | 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 | fn_name, | 4019 | fn_name, |
| 4053 | ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len], | 4020 | ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len], |
| 4054 | scalar_llvm_ty, | 4021 | scalar_llvm_ty, |
| ... | @@ -4069,7 +4036,7 @@ fn buildFloatOp( | ... | @@ -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 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 4040 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 4074 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 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,8 +4048,7 @@ fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4081 | return self.buildFloatOp(.fma, .normal, ty, 3, .{ mulend1, mulend2, addend }); | 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 { | 4051 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4085 | const o = self.object; | | |
| 4086 | const pt = self.pt; | 4052 | const pt = self.pt; |
| 4087 | const zcu = pt.zcu; | 4053 | const zcu = pt.zcu; |
| 4088 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 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,15 +4058,19 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4092 | const rhs = try self.resolveInst(extra.rhs); | 4058 | const rhs = try self.resolveInst(extra.rhs); |
| 4093 | | 4059 | |
| 4094 | const lhs_ty = self.typeOf(extra.lhs); | 4060 | const lhs_ty = self.typeOf(extra.lhs); |
| 4095 | if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) | 4061 | if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) { |
| 4096 | return self.todo("implement vector shifts with scalar rhs", .{}); | 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 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 4067 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); |
| 4098 | | 4068 | |
| 4099 | const dest_ty = self.typeOfIndex(inst); | 4069 | const dest_ty = self.typeOfIndex(inst); |
| 4100 | assert(isByRef(dest_ty, zcu)); // auto structs are by-ref | 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 | const result = try self.wip.bin(.shl, lhs, casted_rhs, ""); | 4075 | const result = try self.wip.bin(.shl, lhs, casted_rhs, ""); |
| 4106 | const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) | 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,29 +4098,28 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4128 | return alloca_inst; | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4102 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4133 | const lhs = try self.resolveInst(bin_op.lhs); | 4103 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4134 | const rhs = try self.resolveInst(bin_op.rhs); | 4104 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4135 | return self.wip.bin(.@"and", lhs, rhs, ""); | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4109 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4140 | const lhs = try self.resolveInst(bin_op.lhs); | 4110 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4141 | const rhs = try self.resolveInst(bin_op.rhs); | 4111 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4142 | return self.wip.bin(.@"or", lhs, rhs, ""); | 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 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 4116 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4147 | const lhs = try self.resolveInst(bin_op.lhs); | 4117 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4148 | const rhs = try self.resolveInst(bin_op.rhs); | 4118 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4149 | return self.wip.bin(.xor, lhs, rhs, ""); | 4119 | return self.wip.bin(.xor, lhs, rhs, ""); |
| 4150 | } | 4120 | } |
| 4151 | | 4121 | |
| 4152 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 4122 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4153 | const o = self.object; | | |
| 4154 | const pt = self.pt; | 4123 | const pt = self.pt; |
| 4155 | const zcu = pt.zcu; | 4124 | const zcu = pt.zcu; |
| 4156 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,19 +4128,21 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4159 | const rhs = try self.resolveInst(bin_op.rhs); | 4128 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4160 | | 4129 | |
| 4161 | const lhs_ty = self.typeOf(bin_op.lhs); | 4130 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4162 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | 4131 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { |
| 4163 | return self.todo("implement vector shifts with scalar rhs", .{}); | 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 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 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 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) | 4139 | return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu)) |
| 4168 | .@"shl nsw" | 4140 | .@"shl nsw" |
| 4169 | else | 4141 | else |
| 4170 | .@"shl nuw", lhs, casted_rhs, ""); | 4142 | .@"shl nuw", lhs, casted_rhs, ""); |
| 4171 | } | 4143 | } |
| 4172 | | 4144 | |
| 4173 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 4145 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4174 | const o = self.object; | | |
| 4175 | const pt = self.pt; | 4146 | const pt = self.pt; |
| 4176 | const zcu = pt.zcu; | 4147 | const zcu = pt.zcu; |
| 4177 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,14 +4151,16 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4180 | const rhs = try self.resolveInst(bin_op.rhs); | 4151 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4181 | | 4152 | |
| 4182 | const lhs_ty = self.typeOf(bin_op.lhs); | 4153 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4183 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | 4154 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { |
| 4184 | return self.todo("implement vector shifts with scalar rhs", .{}); | 4155 | // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize` |
| 4185 | | 4156 | // features which we do not use. Therefore this branch is currently impossible. |
| 4186 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), ""); | 4157 | unreachable; |
| | 4158 | } |
| | 4159 | const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), ""); |
| 4187 | return self.wip.bin(.shl, lhs, casted_rhs, ""); | 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 | const o = self.object; | 4164 | const o = self.object; |
| 4192 | const pt = self.pt; | 4165 | const pt = self.pt; |
| 4193 | const zcu = pt.zcu; | 4166 | const zcu = pt.zcu; |
| ... | @@ -4198,15 +4171,18 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4198,15 +4171,18 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4198 | | 4171 | |
| 4199 | const lhs_ty = self.typeOf(bin_op.lhs); | 4172 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4200 | const lhs_info = lhs_ty.intInfo(zcu); | 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 | const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder); | 4175 | const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder); |
| 4203 | | 4176 | |
| 4204 | const rhs_ty = self.typeOf(bin_op.rhs); | 4177 | const rhs_ty = self.typeOf(bin_op.rhs); |
| 4205 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) | 4178 | if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) { |
| 4206 | return self.todo("implement vector shifts with scalar rhs", .{}); | 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 | const rhs_info = rhs_ty.intInfo(zcu); | 4183 | const rhs_info = rhs_ty.intInfo(zcu); |
| 4208 | assert(rhs_info.signedness == .unsigned); | 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 | const llvm_rhs_scalar_ty = llvm_rhs_ty.scalarType(&o.builder); | 4186 | const llvm_rhs_scalar_ty = llvm_rhs_ty.scalarType(&o.builder); |
| 4211 | | 4187 | |
| 4212 | const result = try self.wip.callIntrinsic( | 4188 | const result = try self.wip.callIntrinsic( |
| ... | @@ -4267,8 +4243,7 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4267,8 +4243,7 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4267 | return self.wip.select(.normal, in_range, result, lhs_sat, ""); | 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 { | 4246 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error!Builder.Value { |
| 4271 | const o = self.object; | | |
| 4272 | const pt = self.pt; | 4247 | const pt = self.pt; |
| 4273 | const zcu = pt.zcu; | 4248 | const zcu = pt.zcu; |
| 4274 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,11 +4252,14 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 4277 | const rhs = try self.resolveInst(bin_op.rhs); | 4252 | const rhs = try self.resolveInst(bin_op.rhs); |
| 4278 | | 4253 | |
| 4279 | const lhs_ty = self.typeOf(bin_op.lhs); | 4254 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 4280 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) | 4255 | if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) { |
| 4281 | return self.todo("implement vector shifts with scalar rhs", .{}); | 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 | const lhs_scalar_ty = lhs_ty.scalarType(zcu); | 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 | const is_signed_int = lhs_scalar_ty.isSignedInt(zcu); | 4263 | const is_signed_int = lhs_scalar_ty.isSignedInt(zcu); |
| 4286 | | 4264 | |
| 4287 | return self.wip.bin(if (is_exact) | 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,7 +4267,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value { |
| 4289 | else if (is_signed_int) .ashr else .lshr, lhs, casted_rhs, ""); | 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 | const o = self.object; | 4271 | const o = self.object; |
| 4294 | const pt = self.pt; | 4272 | const pt = self.pt; |
| 4295 | const zcu = pt.zcu; | 4273 | const zcu = pt.zcu; |
| ... | @@ -4303,7 +4281,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4303,7 +4281,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4303 | .normal, | 4281 | .normal, |
| 4304 | .none, | 4282 | .none, |
| 4305 | .abs, | 4283 | .abs, |
| 4306 | &.{try o.lowerType(pt, operand_ty)}, | 4284 | &.{try self.lowerType(operand_ty)}, |
| 4307 | &.{ operand, try o.builder.intValue(.i1, 0) }, | 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,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 | const o = fg.object; | 4294 | const o = fg.object; |
| 4317 | const pt = fg.pt; | 4295 | const pt = fg.pt; |
| 4318 | const zcu = pt.zcu; | 4296 | const zcu = pt.zcu; |
| 4319 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4297 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4320 | const dest_ty = fg.typeOfIndex(inst); | 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 | const operand = try fg.resolveInst(ty_op.operand); | 4300 | const operand = try fg.resolveInst(ty_op.operand); |
| 4323 | const operand_ty = fg.typeOf(ty_op.operand); | 4301 | const operand_ty = fg.typeOf(ty_op.operand); |
| 4324 | const operand_info = operand_ty.intInfo(zcu); | 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,8 +4324,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4346 | | 4324 | |
| 4347 | if (!have_min_check and !have_max_check) break :bounds_check; | 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); | 4327 | const operand_llvm_ty = try fg.lowerType(operand_ty); |
| 4350 | const operand_scalar_llvm_ty = try o.lowerType(pt, operand_scalar); | 4328 | const operand_scalar_llvm_ty = try fg.lowerType(operand_scalar); |
| 4351 | | 4329 | |
| 4352 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; | 4330 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 4353 | assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector)); | 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,7 +4379,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4401 | }, operand, dest_llvm_ty, ""); | 4379 | }, operand, dest_llvm_ty, ""); |
| 4402 | | 4380 | |
| 4403 | if (safety and dest_is_enum and !dest_ty.isNonexhaustiveEnum(zcu)) { | 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 | const is_valid_enum_val = try fg.wip.call( | 4383 | const is_valid_enum_val = try fg.wip.call( |
| 4406 | .normal, | 4384 | .normal, |
| 4407 | .fastcc, | 4385 | .fastcc, |
| ... | @@ -4422,16 +4400,14 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { | ... | @@ -4422,16 +4400,14 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4422 | return result; | 4400 | return result; |
| 4423 | } | 4401 | } |
| 4424 | | 4402 | |
| 4425 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 4403 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 4426 | const o = self.object; | | |
| 4427 | const pt = self.pt; | | |
| 4428 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4404 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4429 | const operand = try self.resolveInst(ty_op.operand); | 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 | return self.wip.cast(.trunc, operand, dest_llvm_ty, ""); | 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 | const o = self.object; | 4411 | const o = self.object; |
| 4436 | const pt = self.pt; | 4412 | const pt = self.pt; |
| 4437 | const zcu = pt.zcu; | 4413 | const zcu = pt.zcu; |
| ... | @@ -4442,10 +4418,10 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4442,10 +4418,10 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4442 | const target = zcu.getTarget(); | 4418 | const target = zcu.getTarget(); |
| 4443 | | 4419 | |
| 4444 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 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 | } else { | 4422 | } else { |
| 4447 | const operand_llvm_ty = try o.lowerType(pt, operand_ty); | 4423 | const operand_llvm_ty = try self.lowerType(operand_ty); |
| 4448 | const dest_llvm_ty = try o.lowerType(pt, dest_ty); | 4424 | const dest_llvm_ty = try self.lowerType(dest_ty); |
| 4449 | | 4425 | |
| 4450 | const dest_bits = dest_ty.floatBits(target); | 4426 | const dest_bits = dest_ty.floatBits(target); |
| 4451 | const src_bits = operand_ty.floatBits(target); | 4427 | const src_bits = operand_ty.floatBits(target); |
| ... | @@ -4453,7 +4429,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4453,7 +4429,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4453 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | 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 | return self.wip.call( | 4433 | return self.wip.call( |
| 4458 | .normal, | 4434 | .normal, |
| 4459 | .ccc, | 4435 | .ccc, |
| ... | @@ -4466,7 +4442,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -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 | const o = self.object; | 4446 | const o = self.object; |
| 4471 | const pt = self.pt; | 4447 | const pt = self.pt; |
| 4472 | const zcu = pt.zcu; | 4448 | const zcu = pt.zcu; |
| ... | @@ -4477,10 +4453,10 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4477,10 +4453,10 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4477 | const target = zcu.getTarget(); | 4453 | const target = zcu.getTarget(); |
| 4478 | | 4454 | |
| 4479 | if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) { | 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 | } else { | 4457 | } else { |
| 4482 | const operand_llvm_ty = try o.lowerType(pt, operand_ty); | 4458 | const operand_llvm_ty = try self.lowerType(operand_ty); |
| 4483 | const dest_llvm_ty = try o.lowerType(pt, dest_ty); | 4459 | const dest_llvm_ty = try self.lowerType(dest_ty); |
| 4484 | | 4460 | |
| 4485 | const dest_bits = dest_ty.scalarType(zcu).floatBits(target); | 4461 | const dest_bits = dest_ty.scalarType(zcu).floatBits(target); |
| 4486 | const src_bits = operand_ty.scalarType(zcu).floatBits(target); | 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,7 +4464,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4488 | compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits), | 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 | if (dest_ty.isVector(zcu)) return self.buildElementwiseCall( | 4468 | if (dest_ty.isVector(zcu)) return self.buildElementwiseCall( |
| 4493 | libc_fn, | 4469 | libc_fn, |
| 4494 | &.{operand}, | 4470 | &.{operand}, |
| ... | @@ -4507,7 +4483,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -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 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4487 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4512 | const operand_ty = self.typeOf(ty_op.operand); | 4488 | const operand_ty = self.typeOf(ty_op.operand); |
| 4513 | const inst_ty = self.typeOfIndex(inst); | 4489 | const inst_ty = self.typeOfIndex(inst); |
| ... | @@ -4515,13 +4491,13 @@ fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4515,13 +4491,13 @@ fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4515 | return self.bitCast(operand, operand_ty, inst_ty); | 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 | const o = self.object; | 4495 | const o = self.object; |
| 4520 | const pt = self.pt; | 4496 | const pt = self.pt; |
| 4521 | const zcu = pt.zcu; | 4497 | const zcu = pt.zcu; |
| 4522 | const operand_is_ref = isByRef(operand_ty, zcu); | 4498 | const operand_is_ref = isByRef(operand_ty, zcu); |
| 4523 | const result_is_ref = isByRef(inst_ty, zcu); | 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 | if (operand_is_ref and result_is_ref) { | 4502 | if (operand_is_ref and result_is_ref) { |
| 4527 | // They are both pointers, so just return the same opaque pointer :) | 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,11 +4520,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4544 | } | 4520 | } |
| 4545 | | 4521 | |
| 4546 | if (operand_ty.zigTypeTag(zcu) == .vector and inst_ty.zigTypeTag(zcu) == .array) { | 4522 | if (operand_ty.zigTypeTag(zcu) == .vector and inst_ty.zigTypeTag(zcu) == .array) { |
| 4547 | const elem_ty = inst_ty.childType(zcu); | 4523 | const elem_ty = operand_scalar_ty; |
| 4548 | assert(elem_ty.toIntern() == operand_scalar_ty.toIntern()); | 4524 | assert(result_is_ref); // arrays are always by-ref provided they have runtime bits |
| 4549 | if (!result_is_ref) { | | |
| 4550 | return self.todo("implement bitcast vector to non-ref array", .{}); | | |
| 4551 | } | | |
| 4552 | const alignment = inst_ty.abiAlignment(zcu).toLlvm(); | 4525 | const alignment = inst_ty.abiAlignment(zcu).toLlvm(); |
| 4553 | const array_ptr = try self.buildAlloca(llvm_dest_ty, alignment); | 4526 | const array_ptr = try self.buildAlloca(llvm_dest_ty, alignment); |
| 4554 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; | 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,9 +4542,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4569 | return array_ptr; | 4542 | return array_ptr; |
| 4570 | } else if (operand_ty.zigTypeTag(zcu) == .array and inst_ty.zigTypeTag(zcu) == .vector) { | 4543 | } else if (operand_ty.zigTypeTag(zcu) == .array and inst_ty.zigTypeTag(zcu) == .vector) { |
| 4571 | const elem_ty = operand_ty.childType(zcu); | 4544 | const elem_ty = operand_ty.childType(zcu); |
| 4572 | assert(elem_ty.toIntern() == inst_scalar_ty.toIntern()); | 4545 | assert(operand_is_ref); // arrays are always by-ref provided they have runtime bits |
| 4573 | const llvm_vector_ty = try o.lowerType(pt, inst_ty); | 4546 | const llvm_vector_ty = try self.lowerType(inst_ty); |
| 4574 | if (!operand_is_ref) return self.todo("implement bitcast non-ref array to vector", .{}); | | |
| 4575 | | 4547 | |
| 4576 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; | 4548 | const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8; |
| 4577 | if (bitcast_ok) { | 4549 | if (bitcast_ok) { |
| ... | @@ -4582,7 +4554,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty | ... | @@ -4582,7 +4554,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4582 | } else { | 4554 | } else { |
| 4583 | // If the ABI size of the element type is not evenly divisible by size in bits; | 4555 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 4584 | // a simple bitcast will not work, and we fall back to extractelement. | 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 | const elem_size = elem_ty.abiSize(zcu); | 4558 | const elem_size = elem_ty.abiSize(zcu); |
| 4587 | const vector_len = operand_ty.arrayLen(zcu); | 4559 | const vector_len = operand_ty.arrayLen(zcu); |
| 4588 | var vector = try o.builder.poisonValue(llvm_vector_ty); | 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,7 +4596,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty |
| 4624 | return self.wip.cast(.bitcast, operand, llvm_dest_ty, ""); | 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 | const o = self.object; | 4600 | const o = self.object; |
| 4629 | const pt = self.pt; | 4601 | const pt = self.pt; |
| 4630 | const zcu = pt.zcu; | 4602 | const zcu = pt.zcu; |
| ... | @@ -4714,7 +4686,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4714,7 +4686,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4714 | return arg_val; | 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 | const o = self.object; | 4690 | const o = self.object; |
| 4719 | const pt = self.pt; | 4691 | const pt = self.pt; |
| 4720 | const zcu = pt.zcu; | 4692 | const zcu = pt.zcu; |
| ... | @@ -4723,12 +4695,12 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4723,12 +4695,12 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4723 | if (!pointee_type.hasRuntimeBits(zcu)) | 4695 | if (!pointee_type.hasRuntimeBits(zcu)) |
| 4724 | return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue(); | 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 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); | 4699 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); |
| 4728 | return self.buildAlloca(pointee_llvm_ty, alignment); | 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 | const o = self.object; | 4704 | const o = self.object; |
| 4733 | const pt = self.pt; | 4705 | const pt = self.pt; |
| 4734 | const zcu = pt.zcu; | 4706 | const zcu = pt.zcu; |
| ... | @@ -4737,7 +4709,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4737,7 +4709,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4737 | if (!ret_ty.hasRuntimeBits(zcu)) | 4709 | if (!ret_ty.hasRuntimeBits(zcu)) |
| 4738 | return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue(); | 4710 | return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue(); |
| 4739 | if (self.ret_ptr != .none) return self.ret_ptr; | 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 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); | 4713 | const alignment = ptr_ty.ptrAlignment(zcu).toLlvm(); |
| 4742 | return self.buildAlloca(ret_llvm_ty, alignment); | 4714 | return self.buildAlloca(ret_llvm_ty, alignment); |
| 4743 | } | 4715 | } |
| ... | @@ -4753,7 +4725,7 @@ fn buildAlloca( | ... | @@ -4753,7 +4725,7 @@ fn buildAlloca( |
| 4753 | return buildAllocaInner(&self.wip, llvm_ty, alignment, target); | 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 | const o = self.object; | 4729 | const o = self.object; |
| 4758 | const pt = self.pt; | 4730 | const pt = self.pt; |
| 4759 | const zcu = pt.zcu; | 4731 | const zcu = pt.zcu; |
| ... | @@ -4790,7 +4762,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { | ... | @@ -4790,7 +4762,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4790 | | 4762 | |
| 4791 | self.maybeMarkAllowZeroAccess(ptr_info); | 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 | _ = try self.wip.callMemSet( | 4766 | _ = try self.wip.callMemSet( |
| 4795 | dest_ptr, | 4767 | dest_ptr, |
| 4796 | ptr_ty.ptrAlignment(zcu).toLlvm(), | 4768 | ptr_ty.ptrAlignment(zcu).toLlvm(), |
| ... | @@ -4812,7 +4784,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { | ... | @@ -4812,7 +4784,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value { |
| 4812 | return .none; | 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 | const pt = fg.pt; | 4788 | const pt = fg.pt; |
| 4817 | const zcu = pt.zcu; | 4789 | const zcu = pt.zcu; |
| 4818 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 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,7 +4795,7 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4823 | return fg.load(ptr, ptr_ty); | 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 | _ = inst; | 4799 | _ = inst; |
| 4828 | const target = self.pt.zcu.getTarget(); | 4800 | const target = self.pt.zcu.getTarget(); |
| 4829 | if ((target.cpu.arch == .mips or target.cpu.arch == .mipsel) and | 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,17 +4819,16 @@ fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void { |
| 4847 | _ = try self.wip.@"unreachable"(); | 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 | _ = inst; | 4823 | _ = inst; |
| 4852 | _ = try self.wip.callIntrinsic(.normal, .none, .debugtrap, &.{}, &.{}, ""); | 4824 | _ = try self.wip.callIntrinsic(.normal, .none, .debugtrap, &.{}, &.{}, ""); |
| 4853 | return .none; | 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 | _ = inst; | 4829 | _ = inst; |
| 4858 | const o = self.object; | 4830 | const o = self.object; |
| 4859 | const pt = self.pt; | 4831 | const llvm_usize = try self.lowerType(Type.usize); |
| 4860 | const llvm_usize = try o.lowerType(pt, Type.usize); | | |
| 4861 | if (!target_util.supportsReturnAddress(self.pt.zcu.getTarget(), self.ownerModule().optimize_mode)) { | 4832 | if (!target_util.supportsReturnAddress(self.pt.zcu.getTarget(), self.ownerModule().optimize_mode)) { |
| 4862 | // https://github.com/ziglang/zig/issues/11946 | 4833 | // https://github.com/ziglang/zig/issues/11946 |
| 4863 | return o.builder.intValue(llvm_usize, 0); | 4834 | return o.builder.intValue(llvm_usize, 0); |
| ... | @@ -4866,19 +4837,17 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4866,19 +4837,17 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4866 | return self.wip.cast(.ptrtoint, result, llvm_usize, ""); | 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 | _ = inst; | 4841 | _ = inst; |
| 4871 | const o = self.object; | | |
| 4872 | const pt = self.pt; | | |
| 4873 | const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, ""); | 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 | fn airCmpxchg( | 4846 | fn airCmpxchg( |
| 4878 | self: *FuncGen, | 4847 | self: *FuncGen, |
| 4879 | inst: Air.Inst.Index, | 4848 | inst: Air.Inst.Index, |
| 4880 | kind: Builder.Function.Instruction.CmpXchg.Kind, | 4849 | kind: Builder.Function.Instruction.CmpXchg.Kind, |
| 4881 | ) !Builder.Value { | 4850 | ) Allocator.Error!Builder.Value { |
| 4882 | const o = self.object; | 4851 | const o = self.object; |
| 4883 | const pt = self.pt; | 4852 | const pt = self.pt; |
| 4884 | const zcu = pt.zcu; | 4853 | const zcu = pt.zcu; |
| ... | @@ -4889,7 +4858,7 @@ fn airCmpxchg( | ... | @@ -4889,7 +4858,7 @@ fn airCmpxchg( |
| 4889 | var expected_value = try self.resolveInst(extra.expected_value); | 4858 | var expected_value = try self.resolveInst(extra.expected_value); |
| 4890 | var new_value = try self.resolveInst(extra.new_value); | 4859 | var new_value = try self.resolveInst(extra.new_value); |
| 4891 | const operand_ty = ptr_ty.childType(zcu); | 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 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false); | 4862 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false); |
| 4894 | if (llvm_abi_ty != .none) { | 4863 | if (llvm_abi_ty != .none) { |
| 4895 | // operand needs widening and truncating | 4864 | // operand needs widening and truncating |
| ... | @@ -4932,7 +4901,7 @@ fn airCmpxchg( | ... | @@ -4932,7 +4901,7 @@ fn airCmpxchg( |
| 4932 | const non_null_bit = try self.wip.not(success_bit, ""); | 4901 | const non_null_bit = try self.wip.not(success_bit, ""); |
| 4933 | | 4902 | |
| 4934 | const payload_align = operand_ty.abiAlignment(zcu).toLlvm(); | 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 | // Payload is always the first field at offset 0, so address is `alloca_inst` | 4906 | // Payload is always the first field at offset 0, so address is `alloca_inst` |
| 4938 | _ = try self.wip.store(.normal, payload, alloca_inst, payload_align); | 4907 | _ = try self.wip.store(.normal, payload, alloca_inst, payload_align); |
| ... | @@ -4944,7 +4913,7 @@ fn airCmpxchg( | ... | @@ -4944,7 +4913,7 @@ fn airCmpxchg( |
| 4944 | return alloca_inst; | 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 | const o = self.object; | 4917 | const o = self.object; |
| 4949 | const pt = self.pt; | 4918 | const pt = self.pt; |
| 4950 | const zcu = pt.zcu; | 4919 | const zcu = pt.zcu; |
| ... | @@ -4959,7 +4928,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -4959,7 +4928,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 4959 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); | 4928 | const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float); |
| 4960 | const ordering = toLlvmAtomicOrdering(extra.ordering()); | 4929 | const ordering = toLlvmAtomicOrdering(extra.ordering()); |
| 4961 | const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg); | 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 | const access_kind: Builder.MemoryAccessKind = | 4933 | const access_kind: Builder.MemoryAccessKind = |
| 4965 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | 4934 | if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| ... | @@ -5002,7 +4971,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5002,7 +4971,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5002 | access_kind, | 4971 | access_kind, |
| 5003 | op, | 4972 | op, |
| 5004 | ptr, | 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 | self.sync_scope, | 4975 | self.sync_scope, |
| 5007 | ordering, | 4976 | ordering, |
| 5008 | ptr_alignment, | 4977 | ptr_alignment, |
| ... | @@ -5010,8 +4979,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5010,8 +4979,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5010 | ), llvm_operand_ty, ""); | 4979 | ), llvm_operand_ty, ""); |
| 5011 | } | 4980 | } |
| 5012 | | 4981 | |
| 5013 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 4982 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5014 | const o = self.object; | | |
| 5015 | const pt = self.pt; | 4983 | const pt = self.pt; |
| 5016 | const zcu = pt.zcu; | 4984 | const zcu = pt.zcu; |
| 5017 | const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; | 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,7 +4996,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5028 | Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm(); | 4996 | Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm(); |
| 5029 | const access_kind: Builder.MemoryAccessKind = | 4997 | const access_kind: Builder.MemoryAccessKind = |
| 5030 | if (info.flags.is_volatile) .@"volatile" else .normal; | 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 | self.maybeMarkAllowZeroAccess(info); | 5001 | self.maybeMarkAllowZeroAccess(info); |
| 5034 | | 5002 | |
| ... | @@ -5060,7 +5028,7 @@ fn airAtomicStore( | ... | @@ -5060,7 +5028,7 @@ fn airAtomicStore( |
| 5060 | self: *FuncGen, | 5028 | self: *FuncGen, |
| 5061 | inst: Air.Inst.Index, | 5029 | inst: Air.Inst.Index, |
| 5062 | ordering: Builder.AtomicOrdering, | 5030 | ordering: Builder.AtomicOrdering, |
| 5063 | ) !Builder.Value { | 5031 | ) Allocator.Error!Builder.Value { |
| 5064 | const pt = self.pt; | 5032 | const pt = self.pt; |
| 5065 | const zcu = pt.zcu; | 5033 | const zcu = pt.zcu; |
| 5066 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5034 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| ... | @@ -5087,7 +5055,7 @@ fn airAtomicStore( | ... | @@ -5087,7 +5055,7 @@ fn airAtomicStore( |
| 5087 | return .none; | 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 | const o = self.object; | 5059 | const o = self.object; |
| 5092 | const pt = self.pt; | 5060 | const pt = self.pt; |
| 5093 | const zcu = pt.zcu; | 5061 | const zcu = pt.zcu; |
| ... | @@ -5186,7 +5154,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value | ... | @@ -5186,7 +5154,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value |
| 5186 | const body_block = try self.wip.block(1, "InlineMemsetBody"); | 5154 | const body_block = try self.wip.block(1, "InlineMemsetBody"); |
| 5187 | const end_block = try self.wip.block(1, "InlineMemsetEnd"); | 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 | const end_ptr = switch (ptr_ty.ptrSize(zcu)) { | 5158 | const end_ptr = switch (ptr_ty.ptrSize(zcu)) { |
| 5191 | .slice => try self.ptraddScaled( | 5159 | .slice => try self.ptraddScaled( |
| 5192 | dest_ptr, | 5160 | dest_ptr, |
| ... | @@ -5225,7 +5193,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value | ... | @@ -5225,7 +5193,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value |
| 5225 | return .none; | 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 | const pt = self.pt; | 5197 | const pt = self.pt; |
| 5230 | const zcu = pt.zcu; | 5198 | const zcu = pt.zcu; |
| 5231 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,7 +5222,7 @@ fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5254 | return .none; | 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 | const pt = self.pt; | 5226 | const pt = self.pt; |
| 5259 | const zcu = pt.zcu; | 5227 | const zcu = pt.zcu; |
| 5260 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 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,14 +5247,15 @@ fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5279 | return .none; | 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 | const pt = self.pt; | 5251 | const pt = self.pt; |
| 5284 | const zcu = pt.zcu; | 5252 | const zcu = pt.zcu; |
| 5285 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 5253 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5286 | const un_ptr_ty = self.typeOf(bin_op.lhs); | 5254 | const un_ptr_ty = self.typeOf(bin_op.lhs); |
| 5287 | const un_ty = un_ptr_ty.childType(zcu); | 5255 | const un_ty = un_ptr_ty.childType(zcu); |
| 5288 | const layout = un_ty.unionGetLayout(zcu); | 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 | const access_kind: Builder.MemoryAccessKind = | 5260 | const access_kind: Builder.MemoryAccessKind = |
| 5292 | if (un_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; | 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,7 +5278,7 @@ fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5309 | return .none; | 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 | const o = self.object; | 5282 | const o = self.object; |
| 5314 | const pt = self.pt; | 5283 | const pt = self.pt; |
| 5315 | const zcu = pt.zcu; | 5284 | const zcu = pt.zcu; |
| ... | @@ -5319,7 +5288,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5319,7 +5288,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5319 | assert(layout.tag_size != 0); | 5288 | assert(layout.tag_size != 0); |
| 5320 | const union_ptr = try self.resolveInst(ty_op.operand); | 5289 | const union_ptr = try self.resolveInst(ty_op.operand); |
| 5321 | if (isByRef(un_ty, zcu)) { | 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 | if (layout.payload_size == 0) | 5292 | if (layout.payload_size == 0) |
| 5324 | return self.wip.load(.normal, llvm_un_ty, union_ptr, .default, ""); | 5293 | return self.wip.load(.normal, llvm_un_ty, union_ptr, .default, ""); |
| 5325 | const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align)); | 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,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 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5306 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5338 | const operand = try self.resolveInst(un_op); | 5307 | const operand = try self.resolveInst(un_op); |
| 5339 | const operand_ty = self.typeOf(un_op); | 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,7 +5310,7 @@ fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !Build |
| 5341 | return self.buildFloatOp(op, .normal, operand_ty, 1, .{operand}); | 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 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5314 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5346 | const operand = try self.resolveInst(un_op); | 5315 | const operand = try self.resolveInst(un_op); |
| 5347 | const operand_ty = self.typeOf(un_op); | 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,9 +5318,7 @@ fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui |
| 5349 | return self.buildFloatOp(.neg, fast, operand_ty, 1, .{operand}); | 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 { | 5321 | fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { |
| 5353 | const o = self.object; | | |
| 5354 | const pt = self.pt; | | |
| 5355 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5322 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5356 | const inst_ty = self.typeOfIndex(inst); | 5323 | const inst_ty = self.typeOfIndex(inst); |
| 5357 | const operand_ty = self.typeOf(ty_op.operand); | 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,16 +5328,14 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) |
| 5361 | .normal, | 5328 | .normal, |
| 5362 | .none, | 5329 | .none, |
| 5363 | intrinsic, | 5330 | intrinsic, |
| 5364 | &.{try o.lowerType(pt, operand_ty)}, | 5331 | &.{try self.lowerType(operand_ty)}, |
| 5365 | &.{ operand, .false }, | 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 { | 5338 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value { |
| 5372 | const o = self.object; | | |
| 5373 | const pt = self.pt; | | |
| 5374 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5339 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5375 | const inst_ty = self.typeOfIndex(inst); | 5340 | const inst_ty = self.typeOfIndex(inst); |
| 5376 | const operand_ty = self.typeOf(ty_op.operand); | 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,14 +5345,14 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) |
| 5380 | .normal, | 5345 | .normal, |
| 5381 | .none, | 5346 | .none, |
| 5382 | intrinsic, | 5347 | intrinsic, |
| 5383 | &.{try o.lowerType(pt, operand_ty)}, | 5348 | &.{try self.lowerType(operand_ty)}, |
| 5384 | &.{operand}, | 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 | const o = self.object; | 5356 | const o = self.object; |
| 5392 | const pt = self.pt; | 5357 | const pt = self.pt; |
| 5393 | const zcu = pt.zcu; | 5358 | const zcu = pt.zcu; |
| ... | @@ -5398,7 +5363,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5398,7 +5363,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5398 | | 5363 | |
| 5399 | const inst_ty = self.typeOfIndex(inst); | 5364 | const inst_ty = self.typeOfIndex(inst); |
| 5400 | var operand = try self.resolveInst(ty_op.operand); | 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 | if (bits % 16 == 8) { | 5368 | if (bits % 16 == 8) { |
| 5404 | // If not an even byte-multiple, we need zero-extend + shift-left 1 byte | 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,10 +5384,10 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5419 | | 5384 | |
| 5420 | const result = | 5385 | const result = |
| 5421 | try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, ""); | 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 | const o = self.object; | 5391 | const o = self.object; |
| 5427 | const pt = self.pt; | 5392 | const pt = self.pt; |
| 5428 | const zcu = pt.zcu; | 5393 | const zcu = pt.zcu; |
| ... | @@ -5440,7 +5405,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5440,7 +5405,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5440 | | 5405 | |
| 5441 | for (0..names.len) |name_index| { | 5406 | for (0..names.len) |name_index| { |
| 5442 | const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?; | 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 | try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip); | 5409 | try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip); |
| 5445 | } | 5410 | } |
| 5446 | self.wip.cursor = .{ .block = valid_block }; | 5411 | self.wip.cursor = .{ .block = valid_block }; |
| ... | @@ -5455,13 +5420,13 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5455,13 +5420,13 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5455 | return phi.toValue(); | 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 | const o = self.object; | 5424 | const o = self.object; |
| 5460 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5425 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5461 | const operand = try self.resolveInst(un_op); | 5426 | const operand = try self.resolveInst(un_op); |
| 5462 | const enum_ty = self.typeOf(un_op); | 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 | return self.wip.call( | 5430 | return self.wip.call( |
| 5466 | .normal, | 5431 | .normal, |
| 5467 | .fastcc, | 5432 | .fastcc, |
| ... | @@ -5473,28 +5438,7 @@ fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -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 { | 5441 | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 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 { | | |
| 5498 | const o = self.object; | 5442 | const o = self.object; |
| 5499 | const pt = self.pt; | 5443 | const pt = self.pt; |
| 5500 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 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,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 | const o = self.object; | 5461 | const o = self.object; |
| 5518 | const pt = self.pt; | 5462 | const pt = self.pt; |
| 5519 | const zcu = pt.zcu; | 5463 | const zcu = pt.zcu; |
| 5520 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5464 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5521 | const operand = try self.resolveInst(un_op); | 5465 | const operand = try self.resolveInst(un_op); |
| 5522 | const slice_ty = self.typeOfIndex(inst); | 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 | // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed. | 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(); | 5472 | const error_name_table_ptr = try o.getErrorNameTable(); |
| 5529 | const error_name_table = try self.wip.load(.normal, .ptr, error_name_table_ptr.toValue(&o.builder), .default, ""); | 5473 | const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu)); |
| 5530 | const error_name_ptr = try self.ptraddScaled(error_name_table, operand_usize, slice_ty.abiSize(zcu)); | | |
| 5531 | return self.wip.load(.normal, slice_llvm_ty, error_name_ptr, .default, ""); | 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 { | 5477 | fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 5535 | const o = self.object; | | |
| 5536 | const pt = self.pt; | | |
| 5537 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 5478 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5538 | const scalar = try self.resolveInst(ty_op.operand); | 5479 | const scalar = try self.resolveInst(ty_op.operand); |
| 5539 | const vector_ty = self.typeOfIndex(inst); | 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 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 5485 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 5545 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 5486 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 5546 | const pred = try self.resolveInst(pl_op.operand); | 5487 | const pred = try self.resolveInst(pl_op.operand); |
| ... | @@ -5550,7 +5491,7 @@ fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5550,7 +5491,7 @@ fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5550 | return self.wip.select(.normal, pred, a, b, ""); | 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 | const o = fg.object; | 5495 | const o = fg.object; |
| 5555 | const pt = fg.pt; | 5496 | const pt = fg.pt; |
| 5556 | const zcu = pt.zcu; | 5497 | const zcu = pt.zcu; |
| ... | @@ -5561,9 +5502,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5561,9 +5502,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5561 | const operand = try fg.resolveInst(unwrapped.operand); | 5502 | const operand = try fg.resolveInst(unwrapped.operand); |
| 5562 | const mask = unwrapped.mask; | 5503 | const mask = unwrapped.mask; |
| 5563 | const operand_ty = fg.typeOf(unwrapped.operand); | 5504 | const operand_ty = fg.typeOf(unwrapped.operand); |
| 5564 | const llvm_operand_ty = try o.lowerType(pt, operand_ty); | 5505 | const llvm_operand_ty = try fg.lowerType(operand_ty); |
| 5565 | const llvm_result_ty = try o.lowerType(pt, unwrapped.result_ty); | 5506 | const llvm_result_ty = try fg.lowerType(unwrapped.result_ty); |
| 5566 | const llvm_elem_ty = try o.lowerType(pt, unwrapped.result_ty.childType(zcu)); | 5507 | const llvm_elem_ty = try fg.lowerType(unwrapped.result_ty.childType(zcu)); |
| 5567 | const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty); | 5508 | const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty); |
| 5568 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); | 5509 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 5569 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); | 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,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 | const o = fg.object; | 5602 | const o = fg.object; |
| 5662 | const pt = fg.pt; | 5603 | const pt = fg.pt; |
| 5663 | const zcu = pt.zcu; | 5604 | const zcu = pt.zcu; |
| ... | @@ -5666,7 +5607,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5666,7 +5607,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5666 | const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst); | 5607 | const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst); |
| 5667 | | 5608 | |
| 5668 | const mask = unwrapped.mask; | 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 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); | 5611 | const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32); |
| 5671 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); | 5612 | const llvm_poison_mask_elem = try o.builder.poisonConst(.i32); |
| 5672 | | 5613 | |
| ... | @@ -5756,10 +5697,9 @@ fn buildReducedCall( | ... | @@ -5756,10 +5697,9 @@ fn buildReducedCall( |
| 5756 | operand_vector: Builder.Value, | 5697 | operand_vector: Builder.Value, |
| 5757 | vector_len: usize, | 5698 | vector_len: usize, |
| 5758 | accum_init: Builder.Value, | 5699 | accum_init: Builder.Value, |
| 5759 | ) !Builder.Value { | 5700 | ) Allocator.Error!Builder.Value { |
| 5760 | const o = self.object; | 5701 | const o = self.object; |
| 5761 | const pt = self.pt; | 5702 | const usize_ty = try self.lowerType(Type.usize); |
| 5762 | const usize_ty = try o.lowerType(pt, Type.usize); | | |
| 5763 | const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len); | 5703 | const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len); |
| 5764 | const llvm_result_ty = accum_init.typeOfWip(&self.wip); | 5704 | const llvm_result_ty = accum_init.typeOfWip(&self.wip); |
| 5765 | | 5705 | |
| ... | @@ -5811,7 +5751,7 @@ fn buildReducedCall( | ... | @@ -5811,7 +5751,7 @@ fn buildReducedCall( |
| 5811 | return self.wip.load(.normal, llvm_result_ty, accum_ptr, .default, ""); | 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 | const o = self.object; | 5755 | const o = self.object; |
| 5816 | const pt = self.pt; | 5756 | const pt = self.pt; |
| 5817 | const zcu = pt.zcu; | 5757 | const zcu = pt.zcu; |
| ... | @@ -5820,9 +5760,9 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! | ... | @@ -5820,9 +5760,9 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! |
| 5820 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; | 5760 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 5821 | const operand = try self.resolveInst(reduce.operand); | 5761 | const operand = try self.resolveInst(reduce.operand); |
| 5822 | const operand_ty = self.typeOf(reduce.operand); | 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 | const scalar_ty = self.typeOfIndex(inst); | 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 | switch (reduce.operation) { | 5767 | switch (reduce.operation) { |
| 5828 | .And, .Or, .Xor => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) { | 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,8 +5830,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! |
| 5890 | else => unreachable, | 5830 | else => unreachable, |
| 5891 | }; | 5831 | }; |
| 5892 | | 5832 | |
| 5893 | const libc_fn = | 5833 | const libc_fn = try o.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty); |
| 5894 | try self.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty); | | |
| 5895 | const init_val = switch (llvm_scalar_ty) { | 5834 | const init_val = switch (llvm_scalar_ty) { |
| 5896 | .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast( | 5835 | .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast( |
| 5897 | @as(f16, switch (reduce.operation) { | 5836 | @as(f16, switch (reduce.operation) { |
| ... | @@ -5922,7 +5861,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! | ... | @@ -5922,7 +5861,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) ! |
| 5922 | return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val); | 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 | const o = self.object; | 5865 | const o = self.object; |
| 5927 | const pt = self.pt; | 5866 | const pt = self.pt; |
| 5928 | const zcu = pt.zcu; | 5867 | const zcu = pt.zcu; |
| ... | @@ -5931,7 +5870,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5931,7 +5870,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5931 | const result_ty = self.typeOfIndex(inst); | 5870 | const result_ty = self.typeOfIndex(inst); |
| 5932 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | 5871 | const len: usize = @intCast(result_ty.arrayLen(zcu)); |
| 5933 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]); | 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 | switch (result_ty.zigTypeTag(zcu)) { | 5875 | switch (result_ty.zigTypeTag(zcu)) { |
| 5937 | .vector => { | 5876 | .vector => { |
| ... | @@ -5997,7 +5936,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -5997,7 +5936,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5997 | field_ptr_align.toLlvm(), | 5936 | field_ptr_align.toLlvm(), |
| 5998 | llvm_field_val, | 5937 | llvm_field_val, |
| 5999 | field_ty.abiAlignment(zcu).toLlvm(), | 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 | .normal, | 5940 | .normal, |
| 6002 | self.disable_intrinsics, | 5941 | self.disable_intrinsics, |
| 6003 | ); | 5942 | ); |
| ... | @@ -6042,7 +5981,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -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 | const o = self.object; | 5985 | const o = self.object; |
| 6047 | const pt = self.pt; | 5986 | const pt = self.pt; |
| 6048 | const zcu = pt.zcu; | 5987 | const zcu = pt.zcu; |
| ... | @@ -6050,7 +5989,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -6050,7 +5989,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6050 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5989 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6051 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 5990 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 6052 | const union_ty = self.typeOfIndex(inst); | 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 | const union_obj = zcu.typeToUnion(union_ty).?; | 5993 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 6055 | | 5994 | |
| 6056 | assert(union_obj.layout != .@"packed"); | 5995 | assert(union_obj.layout != .@"packed"); |
| ... | @@ -6086,7 +6025,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -6086,7 +6025,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6086 | return result_ptr; | 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 | const o = self.object; | 6029 | const o = self.object; |
| 6091 | const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch; | 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,14 +6074,12 @@ fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6135 | return .none; | 6074 | return .none; |
| 6136 | } | 6075 | } |
| 6137 | | 6076 | |
| 6138 | fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 6077 | fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| 6139 | const o = self.object; | | |
| 6140 | const pt = self.pt; | | |
| 6141 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 6078 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6142 | const inst_ty = self.typeOfIndex(inst); | 6079 | const inst_ty = self.typeOfIndex(inst); |
| 6143 | const operand = try self.resolveInst(ty_op.operand); | 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 | fn workIntrinsic( | 6085 | fn workIntrinsic( |
| ... | @@ -6150,7 +6087,7 @@ fn workIntrinsic( | ... | @@ -6150,7 +6087,7 @@ fn workIntrinsic( |
| 6150 | dimension: u32, | 6087 | dimension: u32, |
| 6151 | default: u32, | 6088 | default: u32, |
| 6152 | comptime basename: []const u8, | 6089 | comptime basename: []const u8, |
| 6153 | ) !Builder.Value { | 6090 | ) Allocator.Error!Builder.Value { |
| 6154 | return self.wip.callIntrinsic(.normal, .none, switch (dimension) { | 6091 | return self.wip.callIntrinsic(.normal, .none, switch (dimension) { |
| 6155 | 0 => @field(Builder.Intrinsic, basename ++ ".x"), | 6092 | 0 => @field(Builder.Intrinsic, basename ++ ".x"), |
| 6156 | 1 => @field(Builder.Intrinsic, basename ++ ".y"), | 6093 | 1 => @field(Builder.Intrinsic, basename ++ ".y"), |
| ... | @@ -6159,7 +6096,7 @@ fn workIntrinsic( | ... | @@ -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 | const target = self.pt.zcu.getTarget(); | 6100 | const target = self.pt.zcu.getTarget(); |
| 6164 | | 6101 | |
| 6165 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 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,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 | const pt = self.pt; | 6113 | const pt = self.pt; |
| 6177 | const target = pt.zcu.getTarget(); | 6114 | const target = pt.zcu.getTarget(); |
| 6178 | | 6115 | |
| ... | @@ -6200,7 +6137,7 @@ fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ... | @@ -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 | const target = self.pt.zcu.getTarget(); | 6141 | const target = self.pt.zcu.getTarget(); |
| 6205 | | 6142 | |
| 6206 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 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,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 | /// Assumes that `Type.optionalReprIsPayload` is `false` for `opt_ty` and that the payload has bits. | 6153 | /// Assumes that `Type.optionalReprIsPayload` is `false` for `opt_ty` and that the payload has bits. |
| 6239 | fn optCmpNull( | 6154 | fn optCmpNull( |
| 6240 | self: *FuncGen, | 6155 | self: *FuncGen, |
| ... | @@ -6258,7 +6173,7 @@ fn optPayloadHandle( | ... | @@ -6258,7 +6173,7 @@ fn optPayloadHandle( |
| 6258 | opt_ptr: Builder.Value, | 6173 | opt_ptr: Builder.Value, |
| 6259 | opt_ty: Type, | 6174 | opt_ty: Type, |
| 6260 | can_elide_load: bool, | 6175 | can_elide_load: bool, |
| 6261 | ) !Builder.Value { | 6176 | ) Allocator.Error!Builder.Value { |
| 6262 | const pt = fg.pt; | 6177 | const pt = fg.pt; |
| 6263 | const zcu = pt.zcu; | 6178 | const zcu = pt.zcu; |
| 6264 | assert(isByRef(opt_ty, zcu)); | 6179 | assert(isByRef(opt_ty, zcu)); |
| ... | @@ -6281,7 +6196,7 @@ fn fieldPtr( | ... | @@ -6281,7 +6196,7 @@ fn fieldPtr( |
| 6281 | aggregate_ptr: Builder.Value, | 6196 | aggregate_ptr: Builder.Value, |
| 6282 | aggregate_ptr_ty: Type, | 6197 | aggregate_ptr_ty: Type, |
| 6283 | field_index: u32, | 6198 | field_index: u32, |
| 6284 | ) !Builder.Value { | 6199 | ) Allocator.Error!Builder.Value { |
| 6285 | const pt = self.pt; | 6200 | const pt = self.pt; |
| 6286 | const zcu = pt.zcu; | 6201 | const zcu = pt.zcu; |
| 6287 | const aggregate_ty = aggregate_ptr_ty.childType(zcu); | 6202 | const aggregate_ty = aggregate_ptr_ty.childType(zcu); |
| ... | @@ -6305,7 +6220,7 @@ fn loadTruncate( | ... | @@ -6305,7 +6220,7 @@ fn loadTruncate( |
| 6305 | payload_ty: Type, | 6220 | payload_ty: Type, |
| 6306 | payload_ptr: Builder.Value, | 6221 | payload_ptr: Builder.Value, |
| 6307 | payload_alignment: Builder.Alignment, | 6222 | payload_alignment: Builder.Alignment, |
| 6308 | ) !Builder.Value { | 6223 | ) Allocator.Error!Builder.Value { |
| 6309 | // from https://llvm.org/docs/LangRef.html#load-instruction : | 6224 | // from https://llvm.org/docs/LangRef.html#load-instruction : |
| 6310 | // "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. " | 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 | // => so load the byte aligned value and trunc the unwanted bits. | 6226 | // => so load the byte aligned value and trunc the unwanted bits. |
| ... | @@ -6313,7 +6228,7 @@ fn loadTruncate( | ... | @@ -6313,7 +6228,7 @@ fn loadTruncate( |
| 6313 | const o = fg.object; | 6228 | const o = fg.object; |
| 6314 | const pt = fg.pt; | 6229 | const pt = fg.pt; |
| 6315 | const zcu = pt.zcu; | 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 | const abi_size = payload_ty.abiSize(zcu); | 6232 | const abi_size = payload_ty.abiSize(zcu); |
| 6318 | | 6233 | |
| 6319 | const load_llvm_ty = if (payload_ty.isAbiInt(zcu)) | 6234 | const load_llvm_ty = if (payload_ty.isAbiInt(zcu)) |
| ... | @@ -6321,7 +6236,7 @@ fn loadTruncate( | ... | @@ -6321,7 +6236,7 @@ fn loadTruncate( |
| 6321 | else | 6236 | else |
| 6322 | payload_llvm_ty; | 6237 | payload_llvm_ty; |
| 6323 | const loaded = try fg.wip.load(access_kind, load_llvm_ty, payload_ptr, payload_alignment, ""); | 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 | try fg.wip.bin(.lshr, loaded, try o.builder.intValue( | 6240 | try fg.wip.bin(.lshr, loaded, try o.builder.intValue( |
| 6326 | load_llvm_ty, | 6241 | load_llvm_ty, |
| 6327 | (payload_ty.abiSize(zcu) - (std.math.divCeil(u64, payload_ty.bitSize(zcu), 8) catch unreachable)) * 8, | 6242 | (payload_ty.abiSize(zcu) - (std.math.divCeil(u64, payload_ty.bitSize(zcu), 8) catch unreachable)) * 8, |
| ... | @@ -6339,10 +6254,10 @@ fn loadByRef( | ... | @@ -6339,10 +6254,10 @@ fn loadByRef( |
| 6339 | pointee_type: Type, | 6254 | pointee_type: Type, |
| 6340 | ptr_alignment: Builder.Alignment, | 6255 | ptr_alignment: Builder.Alignment, |
| 6341 | access_kind: Builder.MemoryAccessKind, | 6256 | access_kind: Builder.MemoryAccessKind, |
| 6342 | ) !Builder.Value { | 6257 | ) Allocator.Error!Builder.Value { |
| 6343 | const o = fg.object; | 6258 | const o = fg.object; |
| 6344 | const pt = fg.pt; | 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 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment) | 6261 | const result_align = InternPool.Alignment.fromLlvm(ptr_alignment) |
| 6347 | .max(pointee_type.abiAlignment(pt.zcu)).toLlvm(); | 6262 | .max(pointee_type.abiAlignment(pt.zcu)).toLlvm(); |
| 6348 | const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align); | 6263 | const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align); |
| ... | @@ -6352,7 +6267,7 @@ fn loadByRef( | ... | @@ -6352,7 +6267,7 @@ fn loadByRef( |
| 6352 | result_align, | 6267 | result_align, |
| 6353 | ptr, | 6268 | ptr, |
| 6354 | ptr_alignment, | 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 | access_kind, | 6271 | access_kind, |
| 6357 | fg.disable_intrinsics, | 6272 | fg.disable_intrinsics, |
| 6358 | ); | 6273 | ); |
| ... | @@ -6362,7 +6277,7 @@ fn loadByRef( | ... | @@ -6362,7 +6277,7 @@ fn loadByRef( |
| 6362 | /// This function always performs a copy. For isByRef=true types, it creates a new | 6277 | /// This function always performs a copy. For isByRef=true types, it creates a new |
| 6363 | /// alloca and copies the value into it, then returns the alloca instruction. | 6278 | /// alloca and copies the value into it, then returns the alloca instruction. |
| 6364 | /// For isByRef=false types, it creates a load instruction and returns it. | 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 | const o = self.object; | 6281 | const o = self.object; |
| 6367 | const pt = self.pt; | 6282 | const pt = self.pt; |
| 6368 | const zcu = pt.zcu; | 6283 | const zcu = pt.zcu; |
| ... | @@ -6380,7 +6295,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { | ... | @@ -6380,7 +6295,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 6380 | | 6295 | |
| 6381 | if (info.flags.vector_index != .none) { | 6296 | if (info.flags.vector_index != .none) { |
| 6382 | const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index); | 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 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); | 6299 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); |
| 6385 | | 6300 | |
| 6386 | const loaded_vector = try self.wip.load(access_kind, vec_ty, ptr, ptr_alignment, ""); | 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,7 +6316,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value { |
| 6401 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); | 6316 | const elem_bits = ptr_ty.childType(zcu).bitSize(zcu); |
| 6402 | const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset); | 6317 | const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset); |
| 6403 | const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, ""); | 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 | if (isByRef(elem_ty, zcu)) { | 6321 | if (isByRef(elem_ty, zcu)) { |
| 6407 | const result_align = elem_ty.abiAlignment(zcu).toLlvm(); | 6322 | const result_align = elem_ty.abiAlignment(zcu).toLlvm(); |
| ... | @@ -6434,7 +6349,7 @@ fn store( | ... | @@ -6434,7 +6349,7 @@ fn store( |
| 6434 | ptr_ty: Type, | 6349 | ptr_ty: Type, |
| 6435 | elem: Builder.Value, | 6350 | elem: Builder.Value, |
| 6436 | ordering: Builder.AtomicOrdering, | 6351 | ordering: Builder.AtomicOrdering, |
| 6437 | ) !void { | 6352 | ) Allocator.Error!void { |
| 6438 | const o = self.object; | 6353 | const o = self.object; |
| 6439 | const pt = self.pt; | 6354 | const pt = self.pt; |
| 6440 | const zcu = pt.zcu; | 6355 | const zcu = pt.zcu; |
| ... | @@ -6449,7 +6364,7 @@ fn store( | ... | @@ -6449,7 +6364,7 @@ fn store( |
| 6449 | | 6364 | |
| 6450 | if (info.flags.vector_index != .none) { | 6365 | if (info.flags.vector_index != .none) { |
| 6451 | const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index); | 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 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); | 6368 | const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty); |
| 6454 | | 6369 | |
| 6455 | const loaded_vector = try self.wip.load(.normal, vec_ty, ptr, ptr_alignment, ""); | 6370 | const loaded_vector = try self.wip.load(.normal, vec_ty, ptr, ptr_alignment, ""); |
| ... | @@ -6518,7 +6433,7 @@ fn store( | ... | @@ -6518,7 +6433,7 @@ fn store( |
| 6518 | ptr_alignment, | 6433 | ptr_alignment, |
| 6519 | elem, | 6434 | elem, |
| 6520 | elem_ty.abiAlignment(zcu).toLlvm(), | 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 | access_kind, | 6437 | access_kind, |
| 6523 | self.disable_intrinsics, | 6438 | self.disable_intrinsics, |
| 6524 | ); | 6439 | ); |
| ... | @@ -6527,8 +6442,7 @@ fn store( | ... | @@ -6527,8 +6442,7 @@ fn store( |
| 6527 | fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void { | 6442 | fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void { |
| 6528 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; | 6443 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; |
| 6529 | const o = fg.object; | 6444 | const o = fg.object; |
| 6530 | const pt = fg.pt; | 6445 | const usize_ty = try fg.lowerType(.usize); |
| 6531 | const usize_ty = try o.lowerType(pt, Type.usize); | | |
| 6532 | const zero = try o.builder.intValue(usize_ty, 0); | 6446 | const zero = try o.builder.intValue(usize_ty, 0); |
| 6533 | const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED); | 6447 | const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED); |
| 6534 | const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, ""); | 6448 | const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, ""); |
| ... | @@ -6551,7 +6465,7 @@ fn valgrindClientRequest( | ... | @@ -6551,7 +6465,7 @@ fn valgrindClientRequest( |
| 6551 | const target = zcu.getTarget(); | 6465 | const target = zcu.getTarget(); |
| 6552 | if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value; | 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 | const usize_alignment = Type.usize.abiAlignment(zcu).toLlvm(); | 6469 | const usize_alignment = Type.usize.abiAlignment(zcu).toLlvm(); |
| 6556 | | 6470 | |
| 6557 | const array_llvm_ty = try o.builder.arrayType(6, llvm_usize); | 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,11 +7274,12 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool { |
| 7360 | => false, | 7274 | => false, |
| 7361 | | 7275 | |
| 7362 | .array, | 7276 | .array, |
| 7363 | .error_union, | | |
| 7364 | .frame, | 7277 | .frame, |
| 7365 | => ty.hasRuntimeBits(zcu), | 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 | .@"struct" => switch (ty.containerLayout(zcu)) { | 7284 | .@"struct" => switch (ty.containerLayout(zcu)) { |
| 7370 | .@"packed" => false, | 7285 | .@"packed" => false, |
| ... | @@ -7402,25 +7317,19 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E | ... | @@ -7402,25 +7317,19 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E |
| 7402 | | 7317 | |
| 7403 | fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value { | 7318 | fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value { |
| 7404 | if (offset == 0) return ptr; | 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 | const offset_val = try fg.object.builder.intValue(llvm_usize_ty, offset); | 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 | fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u64) Allocator.Error!Builder.Value { | 7324 | fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u64) Allocator.Error!Builder.Value { |
| 7410 | switch (scale) { | 7325 | if (scale == 0) return ptr; |
| 7411 | 0 => return ptr, | 7326 | // Right now LLVM seems to fare a bit worse with an explicit `mul nuw` instruction than it does |
| 7412 | 1 => return fg.ptradd(ptr, index), | 7327 | // if we use a bigger type for the GEP, so we'll do that. As I understand it, it has not yet |
| 7413 | else => { | 7328 | // been decided whether the planned `ptradd` instruction will accept a scale or not; if it does |
| 7414 | const o = fg.object; | 7329 | // not then presumably upstream will improve their handling of explicit `mul nuw` computing the |
| 7415 | const llvm_usize_ty = try o.lowerType(fg.pt, .usize); | 7330 | // offset. |
| 7416 | const scale_val = try o.builder.intValue(llvm_usize_ty, scale); | 7331 | const llvm_scale_ty = try fg.object.builder.arrayType(scale, .i8); |
| 7417 | const offset = try fg.wip.bin(.@"mul nuw", index, scale_val, ""); | 7332 | return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, ""); |
| 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}, ""); | | |
| 7424 | } | 7333 | } |
| 7425 | | 7334 | |
| 7426 | fn compilerRtIntBits(bits: u16) ?u16 { | 7335 | fn compilerRtIntBits(bits: u16) ?u16 { |