authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-17 12:24:45+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-10-20 16:14:52+02:00
log230bafa1abb25192500a84d2cccf7e25f67eb7ec
tree13537aa5c8565a77b36c66bfec3d746afbf691da
parent151e15e444cc691546bc30646967ef08dbcc073f
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: simplify allocMem


2 files changed, 70 insertions(+), 116 deletions(-)

src/arch/aarch64/CodeGen.zig+69-111
...@@ -157,40 +157,6 @@ const MCValue = union(enum) {...@@ -157,40 +157,6 @@ const MCValue = union(enum) {
157 condition_flags: Condition,157 condition_flags: Condition,
158 /// The value is a function argument passed via the stack.158 /// The value is a function argument passed via the stack.
159 stack_argument_offset: u32,159 stack_argument_offset: u32,
160
161 fn isMemory(mcv: MCValue) bool {
162 return switch (mcv) {
163 .memory, .stack_offset, .stack_argument_offset => true,
164 else => false,
165 };
166 }
167
168 fn isImmediate(mcv: MCValue) bool {
169 return switch (mcv) {
170 .immediate => true,
171 else => false,
172 };
173 }
174
175 fn isMutable(mcv: MCValue) bool {
176 return switch (mcv) {
177 .none => unreachable,
178 .unreach => unreachable,
179 .dead => unreachable,
180
181 .immediate,
182 .memory,
183 .condition_flags,
184 .ptr_stack_offset,
185 .undef,
186 .stack_argument_offset,
187 => false,
188
189 .register,
190 .stack_offset,
191 => true,
192 };
193 }
194};160};
195161
196const Branch = struct {162const Branch = struct {
...@@ -416,9 +382,7 @@ fn gen(self: *Self) !void {...@@ -416,9 +382,7 @@ fn gen(self: *Self) !void {
416 const ptr_bytes = @divExact(ptr_bits, 8);382 const ptr_bytes = @divExact(ptr_bits, 8);
417 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);383 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);
418384
419 const stack_offset = mem.alignForwardGeneric(u32, self.next_stack_offset, ptr_bytes) + ptr_bytes;385 const stack_offset = try self.allocMem(ptr_bytes, ptr_bytes, null);
420 self.next_stack_offset = stack_offset;
421 self.max_end_stack = @max(self.max_end_stack, self.next_stack_offset);
422386
423 try self.genSetStack(Type.usize, stack_offset, MCValue{ .register = ret_ptr_reg });387 try self.genSetStack(Type.usize, stack_offset, MCValue{ .register = ret_ptr_reg });
424 self.ret_mcv = MCValue{ .stack_offset = stack_offset };388 self.ret_mcv = MCValue{ .stack_offset = stack_offset };
...@@ -879,17 +843,30 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -879,17 +843,30 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
879 }843 }
880}844}
881845
882fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u32 {846fn allocMem(
847 self: *Self,
848 abi_size: u32,
849 abi_align: u32,
850 maybe_inst: ?Air.Inst.Index,
851) !u32 {
852 assert(abi_size > 0);
853 assert(abi_align > 0);
854
883 if (abi_align > self.stack_align)855 if (abi_align > self.stack_align)
884 self.stack_align = abi_align;856 self.stack_align = abi_align;
857
885 // TODO find a free slot instead of always appending858 // TODO find a free slot instead of always appending
886 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align) + abi_size;859 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align) + abi_size;
887 self.next_stack_offset = offset;860 self.next_stack_offset = offset;
888 self.max_end_stack = @max(self.max_end_stack, self.next_stack_offset);861 self.max_end_stack = @max(self.max_end_stack, self.next_stack_offset);
889 try self.stack.putNoClobber(self.gpa, offset, .{862
890 .inst = inst,863 if (maybe_inst) |inst| {
891 .size = abi_size,864 try self.stack.putNoClobber(self.gpa, offset, .{
892 });865 .inst = inst,
866 .size = abi_size,
867 });
868 }
869
893 return offset;870 return offset;
894}871}
895872
...@@ -910,40 +887,41 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -910,40 +887,41 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
910 };887 };
911 // TODO swap this for inst.ty.ptrAlign888 // TODO swap this for inst.ty.ptrAlign
912 const abi_align = elem_ty.abiAlignment(self.target.*);889 const abi_align = elem_ty.abiAlignment(self.target.*);
913 return self.allocMem(inst, abi_size, abi_align);890
891 return self.allocMem(abi_size, abi_align, inst);
914}892}
915893
916fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {894fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
917 const elem_ty = self.air.typeOfIndex(inst);
918 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {895 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
919 const mod = self.bin_file.options.module.?;896 const mod = self.bin_file.options.module.?;
920 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});897 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
921 };898 };
922 const abi_align = elem_ty.abiAlignment(self.target.*);899 const abi_align = elem_ty.abiAlignment(self.target.*);
923 if (abi_align > self.stack_align)
924 self.stack_align = abi_align;
925900
926 if (reg_ok) {901 if (reg_ok) {
927 // Make sure the type can fit in a register before we try to allocate one.902 // Make sure the type can fit in a register before we try to allocate one.
928 if (abi_size <= 8) {903 if (abi_size <= 8) {
929 if (self.register_manager.tryAllocReg(inst, gp)) |reg| {904 if (self.register_manager.tryAllocReg(maybe_inst, gp)) |reg| {
930 return MCValue{ .register = self.registerAlias(reg, elem_ty) };905 return MCValue{ .register = self.registerAlias(reg, elem_ty) };
931 }906 }
932 }907 }
933 }908 }
934 const stack_offset = try self.allocMem(inst, abi_size, abi_align);909
910 const stack_offset = try self.allocMem(abi_size, abi_align, maybe_inst);
935 return MCValue{ .stack_offset = stack_offset };911 return MCValue{ .stack_offset = stack_offset };
936}912}
937913
938pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {914pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
939 const stack_mcv = try self.allocRegOrMem(inst, false);915 const stack_mcv = try self.allocRegOrMem(self.air.typeOfIndex(inst), false, inst);
940 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });916 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });
917
941 const reg_mcv = self.getResolvedInstValue(inst);918 const reg_mcv = self.getResolvedInstValue(inst);
942 switch (reg_mcv) {919 switch (reg_mcv) {
943 .register => |r| assert(reg.id() == r.id()),920 .register => |r| assert(reg.id() == r.id()),
944 .register_with_overflow => |rwo| assert(rwo.reg.id() == reg.id()),921 .register_with_overflow => |rwo| assert(rwo.reg.id() == reg.id()),
945 else => unreachable, // not a register922 else => unreachable, // not a register
946 }923 }
924
947 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];925 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
948 try branch.inst_table.put(self.gpa, inst, stack_mcv);926 try branch.inst_table.put(self.gpa, inst, stack_mcv);
949 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);927 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
...@@ -953,10 +931,11 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -953,10 +931,11 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
953/// occupied931/// occupied
954fn spillCompareFlagsIfOccupied(self: *Self) !void {932fn spillCompareFlagsIfOccupied(self: *Self) !void {
955 if (self.condition_flags_inst) |inst_to_save| {933 if (self.condition_flags_inst) |inst_to_save| {
934 const ty = self.air.typeOfIndex(inst_to_save);
956 const mcv = self.getResolvedInstValue(inst_to_save);935 const mcv = self.getResolvedInstValue(inst_to_save);
957 const new_mcv = switch (mcv) {936 const new_mcv = switch (mcv) {
958 .condition_flags => try self.allocRegOrMem(inst_to_save, true),937 .condition_flags => try self.allocRegOrMem(ty, true, inst_to_save),
959 .register_with_overflow => try self.allocRegOrMem(inst_to_save, false),938 .register_with_overflow => try self.allocRegOrMem(ty, false, inst_to_save),
960 else => unreachable, // mcv doesn't occupy the compare flags939 else => unreachable, // mcv doesn't occupy the compare flags
961 };940 };
962941
...@@ -1046,14 +1025,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1046,14 +1025,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1046 };1025 };
10471026
1048 if (dest_info.bits > operand_info.bits) {1027 if (dest_info.bits > operand_info.bits) {
1049 const dest_mcv = try self.allocRegOrMem(inst, true);1028 const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);
1050 try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);1029 try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);
1051 break :result dest_mcv;1030 break :result dest_mcv;
1052 } else {1031 } else {
1053 if (self.reuseOperand(inst, operand, 0, truncated)) {1032 if (self.reuseOperand(inst, operand, 0, truncated)) {
1054 break :result truncated;1033 break :result truncated;
1055 } else {1034 } else {
1056 const dest_mcv = try self.allocRegOrMem(inst, true);1035 const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);
1057 try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);1036 try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);
1058 break :result dest_mcv;1037 break :result dest_mcv;
1059 }1038 }
...@@ -1278,7 +1257,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1278,7 +1257,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1278 const ptr_bits = self.target.cpu.arch.ptrBitWidth();1257 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
1279 const ptr_bytes = @divExact(ptr_bits, 8);1258 const ptr_bytes = @divExact(ptr_bits, 8);
12801259
1281 const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2);1260 const stack_offset = try self.allocMem(ptr_bytes * 2, ptr_bytes * 2, inst);
1282 try self.genSetStack(ptr_ty, stack_offset, ptr);1261 try self.genSetStack(ptr_ty, stack_offset, ptr);
1283 try self.genSetStack(len_ty, stack_offset - ptr_bytes, len);1262 try self.genSetStack(len_ty, stack_offset - ptr_bytes, len);
1284 break :result MCValue{ .stack_offset = stack_offset };1263 break :result MCValue{ .stack_offset = stack_offset };
...@@ -2049,7 +2028,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2049,7 +2028,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2049 const int_info = lhs_ty.intInfo(self.target.*);2028 const int_info = lhs_ty.intInfo(self.target.*);
2050 switch (int_info.bits) {2029 switch (int_info.bits) {
2051 1...31, 33...63 => {2030 1...31, 33...63 => {
2052 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);2031 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
20532032
2054 try self.spillCompareFlagsIfOccupied();2033 try self.spillCompareFlagsIfOccupied();
2055 self.condition_flags_inst = null;2034 self.condition_flags_inst = null;
...@@ -2164,7 +2143,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2164,7 +2143,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2164 const int_info = lhs_ty.intInfo(self.target.*);2143 const int_info = lhs_ty.intInfo(self.target.*);
21652144
2166 if (int_info.bits <= 32) {2145 if (int_info.bits <= 32) {
2167 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);2146 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
21682147
2169 try self.spillCompareFlagsIfOccupied();2148 try self.spillCompareFlagsIfOccupied();
2170 self.condition_flags_inst = null;2149 self.condition_flags_inst = null;
...@@ -2220,7 +2199,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2220,7 +2199,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
22202199
2221 break :result MCValue{ .stack_offset = stack_offset };2200 break :result MCValue{ .stack_offset = stack_offset };
2222 } else if (int_info.bits <= 64) {2201 } else if (int_info.bits <= 64) {
2223 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);2202 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
22242203
2225 try self.spillCompareFlagsIfOccupied();2204 try self.spillCompareFlagsIfOccupied();
2226 self.condition_flags_inst = null;2205 self.condition_flags_inst = null;
...@@ -2424,7 +2403,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2424,7 +2403,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2424 .Int => {2403 .Int => {
2425 const int_info = lhs_ty.intInfo(self.target.*);2404 const int_info = lhs_ty.intInfo(self.target.*);
2426 if (int_info.bits <= 64) {2405 if (int_info.bits <= 64) {
2427 const stack_offset = try self.allocMem(inst, tuple_size, tuple_align);2406 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
24282407
2429 const lhs_lock: ?RegisterLock = if (lhs == .register)2408 const lhs_lock: ?RegisterLock = if (lhs == .register)
2430 self.register_manager.lockRegAssumeUnused(lhs.register)2409 self.register_manager.lockRegAssumeUnused(lhs.register)
...@@ -2745,7 +2724,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2745,7 +2724,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2745 const base_reg_lock = self.register_manager.lockRegAssumeUnused(base_reg);2724 const base_reg_lock = self.register_manager.lockRegAssumeUnused(base_reg);
2746 defer self.register_manager.unlockReg(base_reg_lock);2725 defer self.register_manager.unlockReg(base_reg_lock);
27472726
2748 const dest = try self.allocRegOrMem(inst, true);2727 const dest = try self.allocRegOrMem(elem_ty, true, inst);
2749 const addr = try self.binOp(.ptr_add, base_mcv, index_mcv, slice_ptr_field_type, Type.usize, null);2728 const addr = try self.binOp(.ptr_add, base_mcv, index_mcv, slice_ptr_field_type, Type.usize, null);
2750 try self.load(dest, addr, slice_ptr_field_type);2729 try self.load(dest, addr, slice_ptr_field_type);
27512730
...@@ -3058,7 +3037,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -3058,7 +3037,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3058 else => ptr,3037 else => ptr,
3059 };3038 };
3060 } else {3039 } else {
3061 break :blk try self.allocRegOrMem(inst, true);3040 break :blk try self.allocRegOrMem(elem_ty, true, inst);
3062 }3041 }
3063 };3042 };
3064 try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));3043 try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));
...@@ -3334,7 +3313,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -3334,7 +3313,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
3334 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});3313 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
3335 };3314 };
3336 const abi_align = ty.abiAlignment(self.target.*);3315 const abi_align = ty.abiAlignment(self.target.*);
3337 const stack_offset = try self.allocMem(inst, abi_size, abi_align);3316 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3338 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });3317 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
33393318
3340 break :blk MCValue{ .stack_offset = stack_offset };3319 break :blk MCValue{ .stack_offset = stack_offset };
...@@ -3412,7 +3391,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions....@@ -3412,7 +3391,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3412 const ret_ty = fn_ty.fnReturnType();3391 const ret_ty = fn_ty.fnReturnType();
3413 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));3392 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
3414 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));3393 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));
3415 const stack_offset = try self.allocMem(inst, ret_abi_size, ret_abi_align);3394 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
34163395
3417 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);3396 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);
34183397
...@@ -3638,14 +3617,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -3638,14 +3617,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
3638 const abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));3617 const abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
3639 const abi_align = ret_ty.abiAlignment(self.target.*);3618 const abi_align = ret_ty.abiAlignment(self.target.*);
36403619
3641 // This is essentially allocMem without the3620 const offset = try self.allocMem(abi_size, abi_align, null);
3642 // instruction tracking
3643 if (abi_align > self.stack_align)
3644 self.stack_align = abi_align;
3645 // TODO find a free slot instead of always appending
3646 const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align) + abi_size;
3647 self.next_stack_offset = offset;
3648 self.max_end_stack = @max(self.max_end_stack, self.next_stack_offset);
36493621
3650 const tmp_mcv = MCValue{ .stack_offset = offset };3622 const tmp_mcv = MCValue{ .stack_offset = offset };
3651 try self.load(tmp_mcv, ptr, ptr_ty);3623 try self.load(tmp_mcv, ptr, ptr_ty);
...@@ -3993,15 +3965,12 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3993,15 +3965,12 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
3993 const un_op = self.air.instructions.items(.data)[inst].un_op;3965 const un_op = self.air.instructions.items(.data)[inst].un_op;
3994 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3966 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3995 const operand_ptr = try self.resolveInst(un_op);3967 const operand_ptr = try self.resolveInst(un_op);
3996 const operand: MCValue = blk: {3968 const ptr_ty = self.air.typeOf(un_op);
3997 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {3969 const elem_ty = ptr_ty.elemType();
3998 // The MCValue that holds the pointer can be re-used as the value.3970
3999 break :blk operand_ptr;3971 const operand = try self.allocRegOrMem(elem_ty, true, null);
4000 } else {3972 try self.load(operand, operand_ptr, ptr_ty);
4001 break :blk try self.allocRegOrMem(inst, true);3973
4002 }
4003 };
4004 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
4005 break :result try self.isNull(operand);3974 break :result try self.isNull(operand);
4006 };3975 };
4007 return self.finishAir(inst, result, .{ un_op, .none, .none });3976 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -4020,15 +3989,12 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4020,15 +3989,12 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4020 const un_op = self.air.instructions.items(.data)[inst].un_op;3989 const un_op = self.air.instructions.items(.data)[inst].un_op;
4021 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3990 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4022 const operand_ptr = try self.resolveInst(un_op);3991 const operand_ptr = try self.resolveInst(un_op);
4023 const operand: MCValue = blk: {3992 const ptr_ty = self.air.typeOf(un_op);
4024 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {3993 const elem_ty = ptr_ty.elemType();
4025 // The MCValue that holds the pointer can be re-used as the value.3994
4026 break :blk operand_ptr;3995 const operand = try self.allocRegOrMem(elem_ty, true, null);
4027 } else {3996 try self.load(operand, operand_ptr, ptr_ty);
4028 break :blk try self.allocRegOrMem(inst, true);3997
4029 }
4030 };
4031 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
4032 break :result try self.isNonNull(operand);3998 break :result try self.isNonNull(operand);
4033 };3999 };
4034 return self.finishAir(inst, result, .{ un_op, .none, .none });4000 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -4049,16 +4015,12 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4049,16 +4015,12 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4049 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4015 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4050 const operand_ptr = try self.resolveInst(un_op);4016 const operand_ptr = try self.resolveInst(un_op);
4051 const ptr_ty = self.air.typeOf(un_op);4017 const ptr_ty = self.air.typeOf(un_op);
4052 const operand: MCValue = blk: {4018 const elem_ty = ptr_ty.elemType();
4053 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {4019
4054 // The MCValue that holds the pointer can be re-used as the value.4020 const operand = try self.allocRegOrMem(elem_ty, true, null);
4055 break :blk operand_ptr;4021 try self.load(operand, operand_ptr, ptr_ty);
4056 } else {4022
4057 break :blk try self.allocRegOrMem(inst, true);4023 break :result try self.isErr(elem_ty, operand);
4058 }
4059 };
4060 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
4061 break :result try self.isErr(ptr_ty.elemType(), operand);
4062 };4024 };
4063 return self.finishAir(inst, result, .{ un_op, .none, .none });4025 return self.finishAir(inst, result, .{ un_op, .none, .none });
4064}4026}
...@@ -4078,16 +4040,12 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4078,16 +4040,12 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4078 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4040 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4079 const operand_ptr = try self.resolveInst(un_op);4041 const operand_ptr = try self.resolveInst(un_op);
4080 const ptr_ty = self.air.typeOf(un_op);4042 const ptr_ty = self.air.typeOf(un_op);
4081 const operand: MCValue = blk: {4043 const elem_ty = ptr_ty.elemType();
4082 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {4044
4083 // The MCValue that holds the pointer can be re-used as the value.4045 const operand = try self.allocRegOrMem(elem_ty, true, null);
4084 break :blk operand_ptr;4046 try self.load(operand, operand_ptr, ptr_ty);
4085 } else {4047
4086 break :blk try self.allocRegOrMem(inst, true);4048 break :result try self.isNonErr(elem_ty, operand);
4087 }
4088 };
4089 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
4090 break :result try self.isNonErr(ptr_ty.elemType(), operand);
4091 };4049 };
4092 return self.finishAir(inst, result, .{ un_op, .none, .none });4050 return self.finishAir(inst, result, .{ un_op, .none, .none });
4093}4051}
...@@ -4180,7 +4138,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -4180,7 +4138,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
4180 .none, .dead, .unreach => unreachable,4138 .none, .dead, .unreach => unreachable,
4181 .register, .stack_offset, .memory => operand_mcv,4139 .register, .stack_offset, .memory => operand_mcv,
4182 .immediate, .stack_argument_offset, .condition_flags => blk: {4140 .immediate, .stack_argument_offset, .condition_flags => blk: {
4183 const new_mcv = try self.allocRegOrMem(block, true);4141 const new_mcv = try self.allocRegOrMem(self.air.typeOfIndex(block), true, block);
4184 try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);4142 try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);
4185 break :blk new_mcv;4143 break :blk new_mcv;
4186 },4144 },
...@@ -4837,7 +4795,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -4837,7 +4795,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
4837 const ptr_bits = self.target.cpu.arch.ptrBitWidth();4795 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
4838 const ptr_bytes = @divExact(ptr_bits, 8);4796 const ptr_bytes = @divExact(ptr_bits, 8);
48394797
4840 const stack_offset = try self.allocMem(inst, ptr_bytes * 2, ptr_bytes * 2);4798 const stack_offset = try self.allocMem(ptr_bytes * 2, ptr_bytes * 2, inst);
4841 try self.genSetStack(ptr_ty, stack_offset, ptr);4799 try self.genSetStack(ptr_ty, stack_offset, ptr);
4842 try self.genSetStack(Type.initTag(.usize), stack_offset - ptr_bytes, .{ .immediate = array_len });4800 try self.genSetStack(Type.initTag(.usize), stack_offset - ptr_bytes, .{ .immediate = array_len });
4843 break :result MCValue{ .stack_offset = stack_offset };4801 break :result MCValue{ .stack_offset = stack_offset };
src/arch/aarch64/Mir.zig+1-5
...@@ -432,7 +432,7 @@ pub const Inst = struct {...@@ -432,7 +432,7 @@ pub const Inst = struct {
432 rn: Register,432 rn: Register,
433 offset: bits.Instruction.LoadStoreOffsetRegister,433 offset: bits.Instruction.LoadStoreOffsetRegister,
434 },434 },
435 /// A registers and a stack offset435 /// A register and a stack offset
436 ///436 ///
437 /// Used by e.g. str_stack437 /// Used by e.g. str_stack
438 load_store_stack: struct {438 load_store_stack: struct {
...@@ -464,10 +464,6 @@ pub const Inst = struct {...@@ -464,10 +464,6 @@ pub const Inst = struct {
464 line: u32,464 line: u32,
465 column: u32,465 column: u32,
466 },466 },
467 load_memory: struct {
468 register: u32,
469 addr: u32,
470 },
471 };467 };
472468
473 // Make sure we don't accidentally make instructions bigger than expected.469 // Make sure we don't accidentally make instructions bigger than expected.