| author | |
| committer | |
| log | c457f35da565e589071db9e55d0866f35cd095dc |
| tree | 45994b3380f17d187f65ed08a61bda4cfa99cac1 |
| parent | f34dcd067b6e9783a53f007746309bb1f635fbf0 |
| signature |
21 files changed, 428 insertions(+), 193 deletions(-)
src/arch/riscv64/CodeGen.zig+396-143| ... | @@ -666,10 +666,11 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt | ... | @@ -666,10 +666,11 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt |
| 666 | if (current_maybe_inst) |current_inst| { | 666 | if (current_maybe_inst) |current_inst| { |
| 667 | try self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst); | 667 | try self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst); |
| 668 | } | 668 | } |
| 669 | { | 669 | blk: { |
| 670 | const inst = target_maybe_inst orelse break :blk; | ||
| 670 | const reg = RegisterManager.regAtTrackedIndex(@intCast(index)); | 671 | const reg = RegisterManager.regAtTrackedIndex(@intCast(index)); |
| 671 | self.register_manager.freeReg(reg); | 672 | self.register_manager.freeReg(reg); |
| 672 | self.register_manager.getRegAssumeFree(reg, target_maybe_inst); | 673 | self.register_manager.getRegAssumeFree(reg, inst); |
| 673 | } | 674 | } |
| 674 | if (target_maybe_inst) |target_inst| { | 675 | if (target_maybe_inst) |target_inst| { |
| 675 | self.inst_tracking.getPtr(target_inst).?.trackMaterialize( | 676 | self.inst_tracking.getPtr(target_inst).?.trackMaterialize( |
| ... | @@ -2272,13 +2273,10 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2272,13 +2273,10 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2272 | }, | 2273 | }, |
| 2273 | }); | 2274 | }); |
| 2274 | 2275 | ||
| 2275 | const add_result_frame: FrameAddr = .{ | 2276 | try self.genSetMem( |
| 2276 | .index = offset.index, | 2277 | .{ .frame = offset.index }, |
| 2277 | .off = offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), | 2278 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))), |
| 2278 | }; | ||
| 2279 | try self.genSetStack( | ||
| 2280 | lhs_ty, | 2279 | lhs_ty, |
| 2281 | add_result_frame, | ||
| 2282 | add_result, | 2280 | add_result, |
| 2283 | ); | 2281 | ); |
| 2284 | 2282 | ||
| ... | @@ -2289,14 +2287,10 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2289,14 +2287,10 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2289 | .{ .register = add_result_reg }, | 2287 | .{ .register = add_result_reg }, |
| 2290 | lhs_ty, | 2288 | lhs_ty, |
| 2291 | ); | 2289 | ); |
| 2292 | 2290 | try self.genSetMem( | |
| 2293 | const overflow_frame: FrameAddr = .{ | 2291 | .{ .frame = offset.index }, |
| 2294 | .index = offset.index, | 2292 | offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), |
| 2295 | .off = offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))), | ||
| 2296 | }; | ||
| 2297 | try self.genSetStack( | ||
| 2298 | Type.u1, | 2293 | Type.u1, |
| 2299 | overflow_frame, | ||
| 2300 | overflow_mcv, | 2294 | overflow_mcv, |
| 2301 | ); | 2295 | ); |
| 2302 | 2296 | ||
| ... | @@ -2340,14 +2334,16 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2340,14 +2334,16 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2340 | 2334 | ||
| 2341 | const tuple_ty = self.typeOfIndex(inst); | 2335 | const tuple_ty = self.typeOfIndex(inst); |
| 2342 | 2336 | ||
| 2343 | // TODO: optimization, set this to true. needs the other struct access stuff to support | 2337 | const result_mcv = try self.allocRegOrMem(inst, true); |
| 2344 | // accessing registers. | ||
| 2345 | const result_mcv = try self.allocRegOrMem(inst, false); | ||
| 2346 | 2338 | ||
| 2347 | const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); | 2339 | const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu)); |
| 2348 | const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); | 2340 | const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, zcu)); |
| 2349 | 2341 | ||
| 2350 | try self.genSetStack(lhs_ty, result_mcv.offset(result_off).load_frame, dest); | 2342 | try self.genCopy( |
| 2343 | lhs_ty, | ||
| 2344 | result_mcv.offset(result_off), | ||
| 2345 | dest, | ||
| 2346 | ); | ||
| 2351 | 2347 | ||
| 2352 | if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { | 2348 | if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { |
| 2353 | if (int_info.signedness == .unsigned) { | 2349 | if (int_info.signedness == .unsigned) { |
| ... | @@ -2385,9 +2381,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2385,9 +2381,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2385 | lhs_ty, | 2381 | lhs_ty, |
| 2386 | ); | 2382 | ); |
| 2387 | 2383 | ||
| 2388 | try self.genSetStack( | 2384 | try self.genCopy( |
| 2389 | lhs_ty, | 2385 | lhs_ty, |
| 2390 | result_mcv.offset(overflow_off).load_frame, | 2386 | result_mcv.offset(overflow_off), |
| 2391 | overflow_mcv, | 2387 | overflow_mcv, |
| 2392 | ); | 2388 | ); |
| 2393 | 2389 | ||
| ... | @@ -2668,9 +2664,9 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2668,9 +2664,9 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2668 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); | 2664 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu)); |
| 2669 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); | 2665 | const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu)); |
| 2670 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); | 2666 | const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu)); |
| 2671 | try self.genSetStack(pl_ty, .{ .index = frame_index, .off = pl_off }, .undef); | 2667 | try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef); |
| 2672 | const operand = try self.resolveInst(ty_op.operand); | 2668 | const operand = try self.resolveInst(ty_op.operand); |
| 2673 | try self.genSetStack(err_ty, .{ .index = frame_index, .off = err_off }, operand); | 2669 | try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand); |
| 2674 | break :result .{ .load_frame = .{ .index = frame_index } }; | 2670 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 2675 | }; | 2671 | }; |
| 2676 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2672 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -2854,7 +2850,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2854,7 +2850,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2854 | switch (array_mcv) { | 2850 | switch (array_mcv) { |
| 2855 | .register => { | 2851 | .register => { |
| 2856 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); | 2852 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu)); |
| 2857 | try self.genSetStack(array_ty, .{ .index = frame_index }, array_mcv); | 2853 | try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); |
| 2858 | try self.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } }); | 2854 | try self.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } }); |
| 2859 | }, | 2855 | }, |
| 2860 | .load_frame => |frame_addr| { | 2856 | .load_frame => |frame_addr| { |
| ... | @@ -2891,9 +2887,48 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2891,9 +2887,48 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2891 | } | 2887 | } |
| 2892 | 2888 | ||
| 2893 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { | 2889 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2890 | const zcu = self.bin_file.comp.module.?; | ||
| 2894 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2891 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2895 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2892 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2896 | const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch}); | 2893 | |
| 2894 | const result = result: { | ||
| 2895 | const elem_ptr_ty = self.typeOfIndex(inst); | ||
| 2896 | const base_ptr_ty = self.typeOf(extra.lhs); | ||
| 2897 | |||
| 2898 | const base_ptr_mcv = try self.resolveInst(extra.lhs); | ||
| 2899 | const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) { | ||
| 2900 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 2901 | else => null, | ||
| 2902 | }; | ||
| 2903 | defer if (base_ptr_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 2904 | |||
| 2905 | if (elem_ptr_ty.ptrInfo(zcu).flags.vector_index != .none) { | ||
| 2906 | break :result if (self.reuseOperand(inst, extra.lhs, 0, base_ptr_mcv)) | ||
| 2907 | base_ptr_mcv | ||
| 2908 | else | ||
| 2909 | try self.copyToNewRegister(inst, base_ptr_mcv); | ||
| 2910 | } | ||
| 2911 | |||
| 2912 | const elem_ty = base_ptr_ty.elemType2(zcu); | ||
| 2913 | const elem_abi_size = elem_ty.abiSize(zcu); | ||
| 2914 | const index_ty = self.typeOf(extra.rhs); | ||
| 2915 | const index_mcv = try self.resolveInst(extra.rhs); | ||
| 2916 | const index_lock: ?RegisterLock = switch (index_mcv) { | ||
| 2917 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 2918 | else => null, | ||
| 2919 | }; | ||
| 2920 | defer if (index_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 2921 | |||
| 2922 | const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size); | ||
| 2923 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); | ||
| 2924 | defer self.register_manager.unlockReg(offset_reg_lock); | ||
| 2925 | |||
| 2926 | if (true) return self.fail("TODO: airPtrElemPtr", .{}); | ||
| 2927 | |||
| 2928 | // TODO: something is breaking here dunno | ||
| 2929 | |||
| 2930 | break :result try self.binOp(.ptr_add, base_ptr_mcv, base_ptr_ty, .{ .register = offset_reg }, base_ptr_ty); | ||
| 2931 | }; | ||
| 2897 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); | 2932 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); |
| 2898 | } | 2933 | } |
| 2899 | 2934 | ||
| ... | @@ -4563,22 +4598,18 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { | ... | @@ -4563,22 +4598,18 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { |
| 4563 | .off = -dst_reg_off.off, | 4598 | .off = -dst_reg_off.off, |
| 4564 | } }, | 4599 | } }, |
| 4565 | }), | 4600 | }), |
| 4566 | .indirect => |ro| { | 4601 | .indirect => |reg_off| try self.genSetMem( |
| 4567 | const src_reg = try self.copyToTmpRegister(ty, src_mcv); | 4602 | .{ .reg = reg_off.reg }, |
| 4568 | 4603 | reg_off.off, | |
| 4569 | _ = try self.addInst(.{ | 4604 | ty, |
| 4570 | .tag = .pseudo, | 4605 | src_mcv, |
| 4571 | .ops = .pseudo_store_rm, | 4606 | ), |
| 4572 | .data = .{ .rm = .{ | 4607 | .load_frame => |frame_addr| try self.genSetMem( |
| 4573 | .r = src_reg, | 4608 | .{ .frame = frame_addr.index }, |
| 4574 | .m = .{ | 4609 | frame_addr.off, |
| 4575 | .base = .{ .reg = ro.reg }, | 4610 | ty, |
| 4576 | .mod = .{ .rm = .{ .disp = ro.off, .size = self.memSize(ty) } }, | 4611 | src_mcv, |
| 4577 | }, | 4612 | ), |
| 4578 | } }, | ||
| 4579 | }); | ||
| 4580 | }, | ||
| 4581 | .load_frame => |frame| return self.genSetStack(ty, frame, src_mcv), | ||
| 4582 | .memory => return self.fail("TODO: genCopy memory", .{}), | 4613 | .memory => return self.fail("TODO: genCopy memory", .{}), |
| 4583 | .register_pair => |dst_regs| { | 4614 | .register_pair => |dst_regs| { |
| 4584 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { | 4615 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { |
| ... | @@ -4617,88 +4648,6 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { | ... | @@ -4617,88 +4648,6 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { |
| 4617 | } | 4648 | } |
| 4618 | } | 4649 | } |
| 4619 | 4650 | ||
| 4620 | fn genSetStack( | ||
| 4621 | self: *Self, | ||
| 4622 | ty: Type, | ||
| 4623 | frame: FrameAddr, | ||
| 4624 | src_mcv: MCValue, | ||
| 4625 | ) InnerError!void { | ||
| 4626 | const zcu = self.bin_file.comp.module.?; | ||
| 4627 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); | ||
| 4628 | |||
| 4629 | switch (src_mcv) { | ||
| 4630 | .none => return, | ||
| 4631 | .dead => unreachable, | ||
| 4632 | .undef => { | ||
| 4633 | if (!self.wantSafety()) return; | ||
| 4634 | try self.genSetStack(ty, frame, .{ .immediate = 0xaaaaaaaaaaaaaaaa }); | ||
| 4635 | }, | ||
| 4636 | .immediate, | ||
| 4637 | .lea_frame, | ||
| 4638 | => { | ||
| 4639 | // TODO: remove this lock in favor of a copyToTmpRegister when we load 64 bit immediates with | ||
| 4640 | // a register allocation. | ||
| 4641 | const reg, const reg_lock = try self.allocReg(); | ||
| 4642 | defer self.register_manager.unlockReg(reg_lock); | ||
| 4643 | |||
| 4644 | try self.genSetReg(ty, reg, src_mcv); | ||
| 4645 | |||
| 4646 | return self.genSetStack(ty, frame, .{ .register = reg }); | ||
| 4647 | }, | ||
| 4648 | .register => |reg| { | ||
| 4649 | switch (abi_size) { | ||
| 4650 | 1, 2, 4, 8 => { | ||
| 4651 | _ = try self.addInst(.{ | ||
| 4652 | .tag = .pseudo, | ||
| 4653 | .ops = .pseudo_store_rm, | ||
| 4654 | .data = .{ .rm = .{ | ||
| 4655 | .r = reg, | ||
| 4656 | .m = .{ | ||
| 4657 | .base = .{ .frame = frame.index }, | ||
| 4658 | .mod = .{ | ||
| 4659 | .rm = .{ | ||
| 4660 | .size = self.memSize(ty), | ||
| 4661 | .disp = frame.off, | ||
| 4662 | }, | ||
| 4663 | }, | ||
| 4664 | }, | ||
| 4665 | } }, | ||
| 4666 | }); | ||
| 4667 | }, | ||
| 4668 | else => unreachable, // register can hold a max of 8 bytes | ||
| 4669 | } | ||
| 4670 | }, | ||
| 4671 | .register_pair => |pair| { | ||
| 4672 | var part_disp: i32 = frame.off; | ||
| 4673 | for (try self.splitType(ty), pair) |src_ty, src_reg| { | ||
| 4674 | try self.genSetStack( | ||
| 4675 | src_ty, | ||
| 4676 | .{ .index = frame.index, .off = part_disp }, | ||
| 4677 | .{ .register = src_reg }, | ||
| 4678 | ); | ||
| 4679 | part_disp += @intCast(src_ty.abiSize(zcu)); | ||
| 4680 | } | ||
| 4681 | }, | ||
| 4682 | .load_frame, | ||
| 4683 | .indirect, | ||
| 4684 | .load_symbol, | ||
| 4685 | => { | ||
| 4686 | if (abi_size <= 8) { | ||
| 4687 | const reg = try self.copyToTmpRegister(ty, src_mcv); | ||
| 4688 | return self.genSetStack(ty, frame, .{ .register = reg }); | ||
| 4689 | } | ||
| 4690 | |||
| 4691 | try self.genInlineMemcpy( | ||
| 4692 | .{ .lea_frame = frame }, | ||
| 4693 | src_mcv.address(), | ||
| 4694 | .{ .immediate = abi_size }, | ||
| 4695 | ); | ||
| 4696 | }, | ||
| 4697 | .air_ref => |ref| try self.genSetStack(ty, frame, try self.resolveInst(ref)), | ||
| 4698 | else => return self.fail("TODO: genSetStack {s}", .{@tagName(src_mcv)}), | ||
| 4699 | } | ||
| 4700 | } | ||
| 4701 | |||
| 4702 | fn genInlineMemcpy( | 4651 | fn genInlineMemcpy( |
| 4703 | self: *Self, | 4652 | self: *Self, |
| 4704 | dst_ptr: MCValue, | 4653 | dst_ptr: MCValue, |
| ... | @@ -4805,6 +4754,86 @@ fn genInlineMemcpy( | ... | @@ -4805,6 +4754,86 @@ fn genInlineMemcpy( |
| 4805 | }); | 4754 | }); |
| 4806 | } | 4755 | } |
| 4807 | 4756 | ||
| 4757 | fn genInlineMemset( | ||
| 4758 | self: *Self, | ||
| 4759 | dst_ptr: MCValue, | ||
| 4760 | src_value: MCValue, | ||
| 4761 | len: MCValue, | ||
| 4762 | ) !void { | ||
| 4763 | const regs = try self.register_manager.allocRegs(3, .{null} ** 3, tp); | ||
| 4764 | const locks = self.register_manager.lockRegsAssumeUnused(3, regs); | ||
| 4765 | defer for (locks) |lock| self.register_manager.unlockReg(lock); | ||
| 4766 | |||
| 4767 | const count = regs[0]; | ||
| 4768 | const src = regs[1]; | ||
| 4769 | const dst = regs[2]; | ||
| 4770 | |||
| 4771 | try self.genSetReg(Type.usize, count, len); | ||
| 4772 | try self.genSetReg(Type.usize, src, src_value); | ||
| 4773 | try self.genSetReg(Type.usize, dst, dst_ptr); | ||
| 4774 | |||
| 4775 | // sb src, 0(dst) | ||
| 4776 | const first_inst = try self.addInst(.{ | ||
| 4777 | .tag = .sb, | ||
| 4778 | .ops = .rri, | ||
| 4779 | .data = .{ | ||
| 4780 | .i_type = .{ | ||
| 4781 | .rd = dst, | ||
| 4782 | .rs1 = src, | ||
| 4783 | .imm12 = Immediate.s(0), | ||
| 4784 | }, | ||
| 4785 | }, | ||
| 4786 | }); | ||
| 4787 | |||
| 4788 | // dec count by 1 | ||
| 4789 | _ = try self.addInst(.{ | ||
| 4790 | .tag = .addi, | ||
| 4791 | .ops = .rri, | ||
| 4792 | .data = .{ | ||
| 4793 | .i_type = .{ | ||
| 4794 | .rd = count, | ||
| 4795 | .rs1 = count, | ||
| 4796 | .imm12 = Immediate.s(-1), | ||
| 4797 | }, | ||
| 4798 | }, | ||
| 4799 | }); | ||
| 4800 | |||
| 4801 | // branch if count is 0 | ||
| 4802 | _ = try self.addInst(.{ | ||
| 4803 | .tag = .beq, | ||
| 4804 | .ops = .rr_inst, | ||
| 4805 | .data = .{ | ||
| 4806 | .b_type = .{ | ||
| 4807 | .inst = @intCast(self.mir_instructions.len + 4), // points after the last inst | ||
| 4808 | .rs1 = count, | ||
| 4809 | .rs2 = .zero, | ||
| 4810 | }, | ||
| 4811 | }, | ||
| 4812 | }); | ||
| 4813 | |||
| 4814 | // increment the pointers | ||
| 4815 | _ = try self.addInst(.{ | ||
| 4816 | .tag = .addi, | ||
| 4817 | .ops = .rri, | ||
| 4818 | .data = .{ | ||
| 4819 | .i_type = .{ | ||
| 4820 | .rd = dst, | ||
| 4821 | .rs1 = dst, | ||
| 4822 | .imm12 = Immediate.s(1), | ||
| 4823 | }, | ||
| 4824 | }, | ||
| 4825 | }); | ||
| 4826 | |||
| 4827 | // jump back to start of loop | ||
| 4828 | _ = try self.addInst(.{ | ||
| 4829 | .tag = .pseudo, | ||
| 4830 | .ops = .pseudo_j, | ||
| 4831 | .data = .{ | ||
| 4832 | .inst = first_inst, | ||
| 4833 | }, | ||
| 4834 | }); | ||
| 4835 | } | ||
| 4836 | |||
| 4808 | /// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it. | 4837 | /// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it. |
| 4809 | fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void { | 4838 | fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void { |
| 4810 | const zcu = self.bin_file.comp.module.?; | 4839 | const zcu = self.bin_file.comp.module.?; |
| ... | @@ -4965,7 +4994,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError! | ... | @@ -4965,7 +4994,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError! |
| 4965 | 2 => .lh, | 4994 | 2 => .lh, |
| 4966 | 4 => .lw, | 4995 | 4 => .lw, |
| 4967 | 8 => .ld, | 4996 | 8 => .ld, |
| 4968 | else => return self.fail("TODO: genSetReg for size {d}", .{abi_size}), | 4997 | else => return std.debug.panic("TODO: genSetReg for size {d}", .{abi_size}), |
| 4969 | }; | 4998 | }; |
| 4970 | 4999 | ||
| 4971 | _ = try self.addInst(.{ | 5000 | _ = try self.addInst(.{ |
| ... | @@ -4998,6 +5027,126 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError! | ... | @@ -4998,6 +5027,126 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError! |
| 4998 | } | 5027 | } |
| 4999 | } | 5028 | } |
| 5000 | 5029 | ||
| 5030 | fn genSetMem( | ||
| 5031 | self: *Self, | ||
| 5032 | base: Memory.Base, | ||
| 5033 | disp: i32, | ||
| 5034 | ty: Type, | ||
| 5035 | src_mcv: MCValue, | ||
| 5036 | ) InnerError!void { | ||
| 5037 | const mod = self.bin_file.comp.module.?; | ||
| 5038 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | ||
| 5039 | const dst_ptr_mcv: MCValue = switch (base) { | ||
| 5040 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, | ||
| 5041 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, | ||
| 5042 | .reloc => |base_symbol| .{ .lea_symbol = .{ .sym = base_symbol.sym_index, .off = disp } }, | ||
| 5043 | }; | ||
| 5044 | switch (src_mcv) { | ||
| 5045 | .none, | ||
| 5046 | .unreach, | ||
| 5047 | .dead, | ||
| 5048 | .reserved_frame, | ||
| 5049 | => unreachable, | ||
| 5050 | .undef => try self.genInlineMemset( | ||
| 5051 | dst_ptr_mcv, | ||
| 5052 | src_mcv, | ||
| 5053 | .{ .immediate = abi_size }, | ||
| 5054 | ), | ||
| 5055 | |||
| 5056 | .register_offset, | ||
| 5057 | .memory, | ||
| 5058 | .indirect, | ||
| 5059 | .load_frame, | ||
| 5060 | .lea_frame, | ||
| 5061 | .load_symbol, | ||
| 5062 | .lea_symbol, | ||
| 5063 | => switch (abi_size) { | ||
| 5064 | 0 => {}, | ||
| 5065 | 1, 2, 4, 8 => { | ||
| 5066 | const src_reg = try self.copyToTmpRegister(ty, src_mcv); | ||
| 5067 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | ||
| 5068 | defer self.register_manager.unlockReg(src_lock); | ||
| 5069 | |||
| 5070 | try self.genSetMem(base, disp, ty, .{ .register = src_reg }); | ||
| 5071 | }, | ||
| 5072 | else => try self.genInlineMemcpy( | ||
| 5073 | dst_ptr_mcv, | ||
| 5074 | src_mcv.address(), | ||
| 5075 | .{ .immediate = abi_size }, | ||
| 5076 | ), | ||
| 5077 | }, | ||
| 5078 | .register => |reg| { | ||
| 5079 | const mem_size = switch (base) { | ||
| 5080 | .frame => |base_fi| mem_size: { | ||
| 5081 | assert(disp >= 0); | ||
| 5082 | const frame_abi_size = self.frame_allocs.items(.abi_size)[@intFromEnum(base_fi)]; | ||
| 5083 | const frame_spill_pad = self.frame_allocs.items(.spill_pad)[@intFromEnum(base_fi)]; | ||
| 5084 | assert(frame_abi_size - frame_spill_pad - disp >= abi_size); | ||
| 5085 | break :mem_size if (frame_abi_size - frame_spill_pad - disp == abi_size) | ||
| 5086 | frame_abi_size | ||
| 5087 | else | ||
| 5088 | abi_size; | ||
| 5089 | }, | ||
| 5090 | else => abi_size, | ||
| 5091 | }; | ||
| 5092 | const src_size = math.ceilPowerOfTwoAssert(u32, abi_size); | ||
| 5093 | const src_align = Alignment.fromNonzeroByteUnits(math.ceilPowerOfTwoAssert(u32, src_size)); | ||
| 5094 | if (src_size > mem_size) { | ||
| 5095 | const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{ | ||
| 5096 | .size = src_size, | ||
| 5097 | .alignment = src_align, | ||
| 5098 | })); | ||
| 5099 | const frame_mcv: MCValue = .{ .load_frame = .{ .index = frame_index } }; | ||
| 5100 | _ = try self.addInst(.{ | ||
| 5101 | .tag = .pseudo, | ||
| 5102 | .ops = .pseudo_store_rm, | ||
| 5103 | .data = .{ | ||
| 5104 | .rm = .{ .r = reg, .m = .{ | ||
| 5105 | .base = .{ .frame = frame_index }, | ||
| 5106 | .mod = .{ .rm = .{ | ||
| 5107 | .size = Memory.Size.fromByteSize(src_size), | ||
| 5108 | } }, | ||
| 5109 | } }, | ||
| 5110 | }, | ||
| 5111 | }); | ||
| 5112 | try self.genSetMem(base, disp, ty, frame_mcv); | ||
| 5113 | try self.freeValue(frame_mcv); | ||
| 5114 | } else _ = try self.addInst(.{ | ||
| 5115 | .tag = .pseudo, | ||
| 5116 | .ops = .pseudo_store_rm, | ||
| 5117 | .data = .{ .rm = .{ | ||
| 5118 | .r = reg, | ||
| 5119 | .m = .{ | ||
| 5120 | .base = base, | ||
| 5121 | .mod = .{ .rm = .{ | ||
| 5122 | .size = self.memSize(ty), | ||
| 5123 | .disp = disp, | ||
| 5124 | } }, | ||
| 5125 | }, | ||
| 5126 | } }, | ||
| 5127 | }); | ||
| 5128 | }, | ||
| 5129 | .register_pair => |src_regs| { | ||
| 5130 | var part_disp: i32 = disp; | ||
| 5131 | for (try self.splitType(ty), src_regs) |src_ty, src_reg| { | ||
| 5132 | try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }); | ||
| 5133 | part_disp += @intCast(src_ty.abiSize(mod)); | ||
| 5134 | } | ||
| 5135 | }, | ||
| 5136 | .immediate => { | ||
| 5137 | // TODO: remove this lock in favor of a copyToTmpRegister when we load 64 bit immediates with | ||
| 5138 | // a register allocation. | ||
| 5139 | const reg, const reg_lock = try self.allocReg(); | ||
| 5140 | defer self.register_manager.unlockReg(reg_lock); | ||
| 5141 | |||
| 5142 | try self.genSetReg(ty, reg, src_mcv); | ||
| 5143 | |||
| 5144 | return self.genSetMem(base, disp, ty, .{ .register = reg }); | ||
| 5145 | }, | ||
| 5146 | .air_ref => |src_ref| try self.genSetMem(base, disp, ty, try self.resolveInst(src_ref)), | ||
| 5147 | } | ||
| 5148 | } | ||
| 5149 | |||
| 5001 | fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { | 5150 | fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5002 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5151 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5003 | const result = result: { | 5152 | const result = result: { |
| ... | @@ -5099,13 +5248,83 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr | ... | @@ -5099,13 +5248,83 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr |
| 5099 | } | 5248 | } |
| 5100 | 5249 | ||
| 5101 | fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | 5250 | fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 5102 | _ = inst; | 5251 | const zcu = self.bin_file.comp.module.?; |
| 5103 | if (safety) { | 5252 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5104 | // TODO if the value is undef, write 0xaa bytes to dest | 5253 | |
| 5105 | } else { | 5254 | result: { |
| 5106 | // TODO if the value is undef, don't lower this instruction | 5255 | if (!safety and (try self.resolveInst(bin_op.rhs)) == .undef) break :result; |
| 5256 | |||
| 5257 | const dst_ptr = try self.resolveInst(bin_op.lhs); | ||
| 5258 | const dst_ptr_ty = self.typeOf(bin_op.lhs); | ||
| 5259 | const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) { | ||
| 5260 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 5261 | else => null, | ||
| 5262 | }; | ||
| 5263 | defer if (dst_ptr_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 5264 | |||
| 5265 | const src_val = try self.resolveInst(bin_op.rhs); | ||
| 5266 | const elem_ty = self.typeOf(bin_op.rhs); | ||
| 5267 | const src_val_lock: ?RegisterLock = switch (src_val) { | ||
| 5268 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 5269 | else => null, | ||
| 5270 | }; | ||
| 5271 | defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 5272 | |||
| 5273 | const elem_abi_size: u31 = @intCast(elem_ty.abiSize(zcu)); | ||
| 5274 | |||
| 5275 | if (elem_abi_size == 1) { | ||
| 5276 | const ptr: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { | ||
| 5277 | // TODO: this only handles slices stored in the stack | ||
| 5278 | .Slice => dst_ptr, | ||
| 5279 | .One => dst_ptr, | ||
| 5280 | .C, .Many => unreachable, | ||
| 5281 | }; | ||
| 5282 | const len: MCValue = switch (dst_ptr_ty.ptrSize(zcu)) { | ||
| 5283 | // TODO: this only handles slices stored in the stack | ||
| 5284 | .Slice => dst_ptr.address().offset(8).deref(), | ||
| 5285 | .One => .{ .immediate = dst_ptr_ty.childType(zcu).arrayLen(zcu) }, | ||
| 5286 | .C, .Many => unreachable, | ||
| 5287 | }; | ||
| 5288 | const len_lock: ?RegisterLock = switch (len) { | ||
| 5289 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 5290 | else => null, | ||
| 5291 | }; | ||
| 5292 | defer if (len_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 5293 | |||
| 5294 | try self.genInlineMemset(ptr, src_val, len); | ||
| 5295 | break :result; | ||
| 5296 | } | ||
| 5297 | |||
| 5298 | // Store the first element, and then rely on memcpy copying forwards. | ||
| 5299 | // Length zero requires a runtime check - so we handle arrays specially | ||
| 5300 | // here to elide it. | ||
| 5301 | switch (dst_ptr_ty.ptrSize(zcu)) { | ||
| 5302 | .Slice => return self.fail("TODO: airMemset Slices", .{}), | ||
| 5303 | .One => { | ||
| 5304 | const elem_ptr_ty = try zcu.singleMutPtrType(elem_ty); | ||
| 5305 | |||
| 5306 | const len = dst_ptr_ty.childType(zcu).arrayLen(zcu); | ||
| 5307 | |||
| 5308 | assert(len != 0); // prevented by Sema | ||
| 5309 | try self.store(dst_ptr, src_val, elem_ptr_ty, elem_ty); | ||
| 5310 | |||
| 5311 | const second_elem_ptr_reg, const second_elem_ptr_lock = try self.allocReg(); | ||
| 5312 | defer self.register_manager.unlockReg(second_elem_ptr_lock); | ||
| 5313 | |||
| 5314 | const second_elem_ptr_mcv: MCValue = .{ .register = second_elem_ptr_reg }; | ||
| 5315 | |||
| 5316 | try self.genSetReg(Type.usize, second_elem_ptr_reg, .{ .register_offset = .{ | ||
| 5317 | .reg = try self.copyToTmpRegister(Type.usize, dst_ptr), | ||
| 5318 | .off = elem_abi_size, | ||
| 5319 | } }); | ||
| 5320 | |||
| 5321 | const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len - 1) }; | ||
| 5322 | try self.genInlineMemcpy(second_elem_ptr_mcv, dst_ptr, bytes_to_copy); | ||
| 5323 | }, | ||
| 5324 | .C, .Many => unreachable, | ||
| 5325 | } | ||
| 5107 | } | 5326 | } |
| 5108 | return self.fail("TODO implement airMemset for {}", .{self.target.cpu.arch}); | 5327 | return self.finishAir(inst, .unreach, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 5109 | } | 5328 | } |
| 5110 | 5329 | ||
| 5111 | fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | 5330 | fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -5190,32 +5409,66 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5190,32 +5409,66 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 5190 | const len: usize = @intCast(result_ty.arrayLen(zcu)); | 5409 | const len: usize = @intCast(result_ty.arrayLen(zcu)); |
| 5191 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 5410 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5192 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]); | 5411 | const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]); |
| 5412 | |||
| 5193 | const result: MCValue = result: { | 5413 | const result: MCValue = result: { |
| 5194 | switch (result_ty.zigTypeTag(zcu)) { | 5414 | switch (result_ty.zigTypeTag(zcu)) { |
| 5195 | .Struct => { | 5415 | .Struct => { |
| 5196 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); | 5416 | const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu)); |
| 5417 | if (result_ty.containerLayout(zcu) == .@"packed") { | ||
| 5418 | const struct_obj = zcu.typeToStruct(result_ty).?; | ||
| 5419 | try self.genInlineMemset( | ||
| 5420 | .{ .lea_frame = .{ .index = frame_index } }, | ||
| 5421 | .{ .immediate = 0 }, | ||
| 5422 | .{ .immediate = result_ty.abiSize(zcu) }, | ||
| 5423 | ); | ||
| 5424 | |||
| 5425 | for (elements, 0..) |elem, elem_i_usize| { | ||
| 5426 | const elem_i: u32 = @intCast(elem_i_usize); | ||
| 5427 | if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue; | ||
| 5428 | |||
| 5429 | const elem_ty = result_ty.structFieldType(elem_i, zcu); | ||
| 5430 | const elem_bit_size: u32 = @intCast(elem_ty.bitSize(zcu)); | ||
| 5431 | if (elem_bit_size > 64) { | ||
| 5432 | return self.fail( | ||
| 5433 | "TODO airAggregateInit implement packed structs with large fields", | ||
| 5434 | .{}, | ||
| 5435 | ); | ||
| 5436 | } | ||
| 5197 | 5437 | ||
| 5198 | if (result_ty.containerLayout(zcu) == .@"packed") {} else for (elements, 0..) |elem, elem_i| { | 5438 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); |
| 5439 | const elem_abi_bits = elem_abi_size * 8; | ||
| 5440 | const elem_off = zcu.structPackedFieldBitOffset(struct_obj, elem_i); | ||
| 5441 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); | ||
| 5442 | const elem_bit_off = elem_off % elem_abi_bits; | ||
| 5443 | const elem_mcv = try self.resolveInst(elem); | ||
| 5444 | |||
| 5445 | _ = elem_byte_off; | ||
| 5446 | _ = elem_bit_off; | ||
| 5447 | |||
| 5448 | const elem_lock = switch (elem_mcv) { | ||
| 5449 | .register => |reg| self.register_manager.lockReg(reg), | ||
| 5450 | .immediate => |imm| lock: { | ||
| 5451 | if (imm == 0) continue; | ||
| 5452 | break :lock null; | ||
| 5453 | }, | ||
| 5454 | else => null, | ||
| 5455 | }; | ||
| 5456 | defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 5457 | |||
| 5458 | return self.fail("TODO: airAggregateInit packed structs", .{}); | ||
| 5459 | } | ||
| 5460 | } else for (elements, 0..) |elem, elem_i| { | ||
| 5199 | if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue; | 5461 | if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue; |
| 5200 | 5462 | ||
| 5201 | const elem_ty = result_ty.structFieldType(elem_i, zcu); | 5463 | const elem_ty = result_ty.structFieldType(elem_i, zcu); |
| 5202 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu)); | 5464 | const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu)); |
| 5203 | const elem_mcv = try self.resolveInst(elem); | 5465 | const elem_mcv = try self.resolveInst(elem); |
| 5204 | 5466 | try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, elem_mcv); | |
| 5205 | const elem_frame: FrameAddr = .{ | ||
| 5206 | .index = frame_index, | ||
| 5207 | .off = elem_off, | ||
| 5208 | }; | ||
| 5209 | try self.genSetStack( | ||
| 5210 | elem_ty, | ||
| 5211 | elem_frame, | ||
| 5212 | elem_mcv, | ||
| 5213 | ); | ||
| 5214 | } | 5467 | } |
| 5468 | break :result .{ .load_frame = .{ .index = frame_index } }; | ||
| 5215 | }, | 5469 | }, |
| 5216 | else => return self.fail("TODO: airAggregateInit {}", .{result_ty.fmt(zcu)}), | 5470 | else => return self.fail("TODO: airAggregate {}", .{result_ty.fmt(zcu)}), |
| 5217 | } | 5471 | } |
| 5218 | break :result .{ .register = .zero }; | ||
| 5219 | }; | 5472 | }; |
| 5220 | 5473 | ||
| 5221 | if (elements.len <= Liveness.bpi - 1) { | 5474 | if (elements.len <= Liveness.bpi - 1) { |
src/arch/riscv64/abi.zig+13| ... | @@ -169,6 +169,19 @@ pub fn classifySystem(ty: Type, zcu: *Module) [8]Class { | ... | @@ -169,6 +169,19 @@ pub fn classifySystem(ty: Type, zcu: *Module) [8]Class { |
| 169 | 169 | ||
| 170 | return memory_class; | 170 | return memory_class; |
| 171 | }, | 171 | }, |
| 172 | .Array => { | ||
| 173 | const ty_size = ty.abiSize(zcu); | ||
| 174 | if (ty_size <= 8) { | ||
| 175 | result[0] = .integer; | ||
| 176 | return result; | ||
| 177 | } | ||
| 178 | if (ty_size <= 16) { | ||
| 179 | result[0] = .integer; | ||
| 180 | result[1] = .integer; | ||
| 181 | return result; | ||
| 182 | } | ||
| 183 | return memory_class; | ||
| 184 | }, | ||
| 172 | else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}), | 185 | else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}), |
| 173 | } | 186 | } |
| 174 | } | 187 | } |
src/arch/riscv64/bits.zig+19-8| ... | @@ -35,10 +35,10 @@ pub const Memory = struct { | ... | @@ -35,10 +35,10 @@ pub const Memory = struct { |
| 35 | 35 | ||
| 36 | pub fn fromByteSize(size: u64) Size { | 36 | pub fn fromByteSize(size: u64) Size { |
| 37 | return switch (size) { | 37 | return switch (size) { |
| 38 | 1 => .byte, | 38 | 1...1 => .byte, |
| 39 | 2 => .hword, | 39 | 2...2 => .hword, |
| 40 | 4 => .word, | 40 | 3...4 => .word, |
| 41 | 8 => .dword, | 41 | 5...8 => .dword, |
| 42 | else => unreachable, | 42 | else => unreachable, |
| 43 | }; | 43 | }; |
| 44 | } | 44 | } |
| ... | @@ -149,10 +149,8 @@ pub const Immediate = union(enum) { | ... | @@ -149,10 +149,8 @@ pub const Immediate = union(enum) { |
| 149 | 149 | ||
| 150 | pub const Register = enum(u6) { | 150 | pub const Register = enum(u6) { |
| 151 | // zig fmt: off | 151 | // zig fmt: off |
| 152 | x0, x1, x2, x3, x4, x5, x6, x7, | 152 | |
| 153 | x8, x9, x10, x11, x12, x13, x14, x15, | 153 | // general purpose registers |
| 154 | x16, x17, x18, x19, x20, x21, x22, x23, | ||
| 155 | x24, x25, x26, x27, x28, x29, x30, x31, | ||
| 156 | 154 | ||
| 157 | zero, // zero | 155 | zero, // zero |
| 158 | ra, // return address. caller saved | 156 | ra, // return address. caller saved |
| ... | @@ -166,6 +164,13 @@ pub const Register = enum(u6) { | ... | @@ -166,6 +164,13 @@ pub const Register = enum(u6) { |
| 166 | a2, a3, a4, a5, a6, a7, // fn args. caller saved. | 164 | a2, a3, a4, a5, a6, a7, // fn args. caller saved. |
| 167 | s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, // saved registers. callee saved. | 165 | s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, // saved registers. callee saved. |
| 168 | t3, t4, t5, t6, // caller saved | 166 | t3, t4, t5, t6, // caller saved |
| 167 | |||
| 168 | x0, x1, x2, x3, x4, x5, x6, x7, | ||
| 169 | x8, x9, x10, x11, x12, x13, x14, x15, | ||
| 170 | x16, x17, x18, x19, x20, x21, x22, x23, | ||
| 171 | x24, x25, x26, x27, x28, x29, x30, x31, | ||
| 172 | |||
| 173 | |||
| 169 | // zig fmt: on | 174 | // zig fmt: on |
| 170 | 175 | ||
| 171 | /// Returns the unique 5-bit ID of this register which is used in | 176 | /// Returns the unique 5-bit ID of this register which is used in |
| ... | @@ -177,6 +182,12 @@ pub const Register = enum(u6) { | ... | @@ -177,6 +182,12 @@ pub const Register = enum(u6) { |
| 177 | pub fn dwarfLocOp(reg: Register) u8 { | 182 | pub fn dwarfLocOp(reg: Register) u8 { |
| 178 | return @as(u8, reg.id()); | 183 | return @as(u8, reg.id()); |
| 179 | } | 184 | } |
| 185 | |||
| 186 | pub fn bitSize(reg: Register) u32 { | ||
| 187 | return switch (@intFromEnum(reg)) { | ||
| 188 | @intFromEnum(Register.zero)...@intFromEnum(Register.x31) => 64, | ||
| 189 | }; | ||
| 190 | } | ||
| 180 | }; | 191 | }; |
| 181 | 192 | ||
| 182 | pub const FrameIndex = enum(u32) { | 193 | pub const FrameIndex = enum(u32) { |
test/behavior/alignof.zig-2| ... | @@ -29,8 +29,6 @@ test "comparison of @alignOf(T) against zero" { | ... | @@ -29,8 +29,6 @@ test "comparison of @alignOf(T) against zero" { |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | test "correct alignment for elements and slices of aligned array" { | 31 | test "correct alignment for elements and slices of aligned array" { |
| 32 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 33 | |||
| 34 | var buf: [1024]u8 align(64) = undefined; | 32 | var buf: [1024]u8 align(64) = undefined; |
| 35 | var start: usize = 1; | 33 | var start: usize = 1; |
| 36 | var end: usize = undefined; | 34 | var end: usize = undefined; |
test/behavior/array.zig-4| ... | @@ -231,7 +231,6 @@ test "nested arrays of integers" { | ... | @@ -231,7 +231,6 @@ test "nested arrays of integers" { |
| 231 | test "implicit comptime in array type size" { | 231 | test "implicit comptime in array type size" { |
| 232 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 232 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 233 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 233 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 234 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 235 | 234 | ||
| 236 | var arr: [plusOne(10)]bool = undefined; | 235 | var arr: [plusOne(10)]bool = undefined; |
| 237 | _ = &arr; | 236 | _ = &arr; |
| ... | @@ -505,7 +504,6 @@ test "anonymous literal in array" { | ... | @@ -505,7 +504,6 @@ test "anonymous literal in array" { |
| 505 | test "access the null element of a null terminated array" { | 504 | test "access the null element of a null terminated array" { |
| 506 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 505 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 507 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 506 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 508 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 509 | 507 | ||
| 510 | const S = struct { | 508 | const S = struct { |
| 511 | fn doTheTest() !void { | 509 | fn doTheTest() !void { |
| ... | @@ -778,8 +776,6 @@ test "slicing array of zero-sized values" { | ... | @@ -778,8 +776,6 @@ test "slicing array of zero-sized values" { |
| 778 | } | 776 | } |
| 779 | 777 | ||
| 780 | test "array init with no result pointer sets field result types" { | 778 | test "array init with no result pointer sets field result types" { |
| 781 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 782 | |||
| 783 | const S = struct { | 779 | const S = struct { |
| 784 | // A function parameter has a result type, but no result pointer. | 780 | // A function parameter has a result type, but no result pointer. |
| 785 | fn f(arr: [1]u32) u32 { | 781 | fn f(arr: [1]u32) u32 { |
test/behavior/cast.zig-3| ... | @@ -1695,7 +1695,6 @@ test "peer type resolution: const sentinel slice and mutable non-sentinel slice" | ... | @@ -1695,7 +1695,6 @@ test "peer type resolution: const sentinel slice and mutable non-sentinel slice" |
| 1695 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1695 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1696 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1696 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1697 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1697 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1698 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1699 | 1698 | ||
| 1700 | const S = struct { | 1699 | const S = struct { |
| 1701 | fn doTheTest(comptime T: type, comptime s: T) !void { | 1700 | fn doTheTest(comptime T: type, comptime s: T) !void { |
| ... | @@ -1866,7 +1865,6 @@ test "peer type resolution: C pointer and @TypeOf(null)" { | ... | @@ -1866,7 +1865,6 @@ test "peer type resolution: C pointer and @TypeOf(null)" { |
| 1866 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1865 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1867 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1866 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1868 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1867 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1869 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1870 | 1868 | ||
| 1871 | var a: [*c]c_int = 0x1000; | 1869 | var a: [*c]c_int = 0x1000; |
| 1872 | _ = &a; | 1870 | _ = &a; |
| ... | @@ -2240,7 +2238,6 @@ test "peer type resolution: C pointer and many pointer" { | ... | @@ -2240,7 +2238,6 @@ test "peer type resolution: C pointer and many pointer" { |
| 2240 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2238 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2241 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2239 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2242 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2240 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2243 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 2244 | 2241 | ||
| 2245 | var buf = "hello".*; | 2242 | var buf = "hello".*; |
| 2246 | 2243 |
test/behavior/eval.zig-1| ... | @@ -73,7 +73,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 { | ... | @@ -73,7 +73,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 { |
| 73 | test "constant expressions" { | 73 | test "constant expressions" { |
| 74 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 74 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 75 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 75 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 76 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 77 | 76 | ||
| 78 | var array: [array_size]u8 = undefined; | 77 | var array: [array_size]u8 = undefined; |
| 79 | _ = &array; | 78 | _ = &array; |
test/behavior/extern.zig-2| ... | @@ -20,7 +20,6 @@ test "function extern symbol" { | ... | @@ -20,7 +20,6 @@ test "function extern symbol" { |
| 20 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 20 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 21 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 21 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 22 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 22 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 23 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 24 | 23 | ||
| 25 | const a = @extern(*const fn () callconv(.C) i32, .{ .name = "a_mystery_function" }); | 24 | const a = @extern(*const fn () callconv(.C) i32, .{ .name = "a_mystery_function" }); |
| 26 | try expect(a() == 4567); | 25 | try expect(a() == 4567); |
| ... | @@ -34,7 +33,6 @@ test "function extern symbol matches extern decl" { | ... | @@ -34,7 +33,6 @@ test "function extern symbol matches extern decl" { |
| 34 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 33 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 35 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; | 34 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; |
| 36 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 35 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 37 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 38 | 36 | ||
| 39 | const S = struct { | 37 | const S = struct { |
| 40 | extern fn another_mystery_function() u32; | 38 | extern fn another_mystery_function() u32; |
test/behavior/fn.zig-2| ... | @@ -414,8 +414,6 @@ test "ability to give comptime types and non comptime types to same parameter" { | ... | @@ -414,8 +414,6 @@ test "ability to give comptime types and non comptime types to same parameter" { |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | test "function with inferred error set but returning no error" { | 416 | test "function with inferred error set but returning no error" { |
| 417 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 418 | |||
| 419 | const S = struct { | 417 | const S = struct { |
| 420 | fn foo() !void {} | 418 | fn foo() !void {} |
| 421 | }; | 419 | }; |
test/behavior/for.zig-1| ... | @@ -487,7 +487,6 @@ test "ref counter that starts at zero" { | ... | @@ -487,7 +487,6 @@ test "ref counter that starts at zero" { |
| 487 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 487 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 488 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 488 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 489 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 489 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 490 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 491 | 490 | ||
| 492 | for ([_]usize{ 0, 1, 2 }, 0..) |i, j| { | 491 | for ([_]usize{ 0, 1, 2 }, 0..) |i, j| { |
| 493 | try expectEqual(i, j); | 492 | try expectEqual(i, j); |
test/behavior/generics.zig-1| ... | @@ -117,7 +117,6 @@ test "function with return type type" { | ... | @@ -117,7 +117,6 @@ test "function with return type type" { |
| 117 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 117 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 118 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 118 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 120 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 121 | 120 | ||
| 122 | var list: List(i32) = undefined; | 121 | var list: List(i32) = undefined; |
| 123 | var list2: List(i32) = undefined; | 122 | var list2: List(i32) = undefined; |
test/behavior/maximum_minimum.zig-1| ... | @@ -300,7 +300,6 @@ test "@min/@max notices bounds from vector types when element of comptime-known | ... | @@ -300,7 +300,6 @@ test "@min/@max notices bounds from vector types when element of comptime-known |
| 300 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 300 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 301 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 301 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 302 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 302 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 303 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 304 | if (builtin.zig_backend == .stage2_x86_64 and | 303 | if (builtin.zig_backend == .stage2_x86_64 and |
| 305 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx)) return error.SkipZigTest; | 304 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx)) return error.SkipZigTest; |
| 306 | 305 |
test/behavior/member_func.zig-1| ... | @@ -76,7 +76,6 @@ test "@field field calls" { | ... | @@ -76,7 +76,6 @@ test "@field field calls" { |
| 76 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 76 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 77 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 78 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 78 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 79 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 80 | 79 | ||
| 81 | try expect(@field(HasFuncs, "one")(0) == 1); | 80 | try expect(@field(HasFuncs, "one")(0) == 1); |
| 82 | try expect(@field(HasFuncs, "two")(0) == 2); | 81 | try expect(@field(HasFuncs, "two")(0) == 2); |
test/behavior/memset.zig-3| ... | @@ -73,7 +73,6 @@ test "memset with bool element" { | ... | @@ -73,7 +73,6 @@ test "memset with bool element" { |
| 73 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 73 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 74 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 74 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 75 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 75 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 76 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 77 | 76 | ||
| 78 | var buf: [5]bool = undefined; | 77 | var buf: [5]bool = undefined; |
| 79 | @memset(&buf, true); | 78 | @memset(&buf, true); |
| ... | @@ -86,7 +85,6 @@ test "memset with 1-byte struct element" { | ... | @@ -86,7 +85,6 @@ test "memset with 1-byte struct element" { |
| 86 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 85 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 87 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 86 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 88 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 87 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 89 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 90 | 88 | ||
| 91 | const S = struct { x: bool }; | 89 | const S = struct { x: bool }; |
| 92 | var buf: [5]S = undefined; | 90 | var buf: [5]S = undefined; |
| ... | @@ -100,7 +98,6 @@ test "memset with 1-byte array element" { | ... | @@ -100,7 +98,6 @@ test "memset with 1-byte array element" { |
| 100 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 98 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 101 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 99 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 102 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 100 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 103 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 104 | 101 | ||
| 105 | const A = [1]bool; | 102 | const A = [1]bool; |
| 106 | var buf: [5]A = undefined; | 103 | var buf: [5]A = undefined; |
test/behavior/packed-struct.zig-1| ... | @@ -435,7 +435,6 @@ test "nested packed struct field pointers" { | ... | @@ -435,7 +435,6 @@ test "nested packed struct field pointers" { |
| 435 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 435 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 436 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 436 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 437 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access | 437 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access |
| 438 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 439 | if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet | 438 | if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet |
| 440 | 439 | ||
| 441 | const S2 = packed struct { | 440 | const S2 = packed struct { |
test/behavior/ptrcast.zig-1| ... | @@ -58,7 +58,6 @@ fn testReinterpretStructWrappedBytesAsInteger() !void { | ... | @@ -58,7 +58,6 @@ fn testReinterpretStructWrappedBytesAsInteger() !void { |
| 58 | test "reinterpret bytes of an array into an extern struct" { | 58 | test "reinterpret bytes of an array into an extern struct" { |
| 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 60 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 60 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 61 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 62 | 61 | ||
| 63 | try testReinterpretBytesAsExternStruct(); | 62 | try testReinterpretBytesAsExternStruct(); |
| 64 | try comptime testReinterpretBytesAsExternStruct(); | 63 | try comptime testReinterpretBytesAsExternStruct(); |
test/behavior/ptrfromint.zig-1| ... | @@ -47,7 +47,6 @@ test "@ptrFromInt creates allowzero zero pointer" { | ... | @@ -47,7 +47,6 @@ test "@ptrFromInt creates allowzero zero pointer" { |
| 47 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 47 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 48 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 48 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 49 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 51 | 50 | ||
| 52 | const ptr = @as(*allowzero u32, @ptrFromInt(0)); | 51 | const ptr = @as(*allowzero u32, @ptrFromInt(0)); |
| 53 | try expectEqual(@as(usize, 0), @intFromPtr(ptr)); | 52 | try expectEqual(@as(usize, 0), @intFromPtr(ptr)); |
test/behavior/return_address.zig-1| ... | @@ -10,7 +10,6 @@ test "return address" { | ... | @@ -10,7 +10,6 @@ test "return address" { |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 13 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 14 | 13 | ||
| 15 | _ = retAddr(); | 14 | _ = retAddr(); |
| 16 | // TODO: #14938 | 15 | // TODO: #14938 |
test/behavior/struct.zig-10| ... | @@ -111,7 +111,6 @@ fn testMutation(foo: *StructFoo) void { | ... | @@ -111,7 +111,6 @@ fn testMutation(foo: *StructFoo) void { |
| 111 | 111 | ||
| 112 | test "struct byval assign" { | 112 | test "struct byval assign" { |
| 113 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 113 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 114 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 115 | 114 | ||
| 116 | var foo1: StructFoo = undefined; | 115 | var foo1: StructFoo = undefined; |
| 117 | var foo2: StructFoo = undefined; | 116 | var foo2: StructFoo = undefined; |
| ... | @@ -300,7 +299,6 @@ const Val = struct { | ... | @@ -300,7 +299,6 @@ const Val = struct { |
| 300 | test "struct point to self" { | 299 | test "struct point to self" { |
| 301 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 300 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 302 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 301 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 303 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 304 | 302 | ||
| 305 | var root: Node = undefined; | 303 | var root: Node = undefined; |
| 306 | root.val.x = 1; | 304 | root.val.x = 1; |
| ... | @@ -1023,7 +1021,6 @@ test "struct with 0-length union array field" { | ... | @@ -1023,7 +1021,6 @@ test "struct with 0-length union array field" { |
| 1023 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1021 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1024 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1022 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1025 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1023 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1026 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1027 | 1024 | ||
| 1028 | const U = union { | 1025 | const U = union { |
| 1029 | a: u32, | 1026 | a: u32, |
| ... | @@ -1732,7 +1729,6 @@ test "extern struct field pointer has correct alignment" { | ... | @@ -1732,7 +1729,6 @@ test "extern struct field pointer has correct alignment" { |
| 1732 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1729 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1733 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1730 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1734 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1731 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1735 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1736 | 1732 | ||
| 1737 | const S = struct { | 1733 | const S = struct { |
| 1738 | fn doTheTest() !void { | 1734 | fn doTheTest() !void { |
| ... | @@ -1863,8 +1859,6 @@ test "comptimeness of optional and error union payload is analyzed properly" { | ... | @@ -1863,8 +1859,6 @@ test "comptimeness of optional and error union payload is analyzed properly" { |
| 1863 | } | 1859 | } |
| 1864 | 1860 | ||
| 1865 | test "initializer uses own alignment" { | 1861 | test "initializer uses own alignment" { |
| 1866 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1867 | |||
| 1868 | const S = struct { | 1862 | const S = struct { |
| 1869 | x: u32 = @alignOf(@This()) + 1, | 1863 | x: u32 = @alignOf(@This()) + 1, |
| 1870 | }; | 1864 | }; |
| ... | @@ -1876,8 +1870,6 @@ test "initializer uses own alignment" { | ... | @@ -1876,8 +1870,6 @@ test "initializer uses own alignment" { |
| 1876 | } | 1870 | } |
| 1877 | 1871 | ||
| 1878 | test "initializer uses own size" { | 1872 | test "initializer uses own size" { |
| 1879 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1880 | |||
| 1881 | const S = struct { | 1873 | const S = struct { |
| 1882 | x: u32 = @sizeOf(@This()) + 1, | 1874 | x: u32 = @sizeOf(@This()) + 1, |
| 1883 | }; | 1875 | }; |
| ... | @@ -1889,8 +1881,6 @@ test "initializer uses own size" { | ... | @@ -1889,8 +1881,6 @@ test "initializer uses own size" { |
| 1889 | } | 1881 | } |
| 1890 | 1882 | ||
| 1891 | test "initializer takes a pointer to a variable inside its struct" { | 1883 | test "initializer takes a pointer to a variable inside its struct" { |
| 1892 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1893 | |||
| 1894 | const namespace = struct { | 1884 | const namespace = struct { |
| 1895 | const S = struct { | 1885 | const S = struct { |
| 1896 | s: *S = &S.instance, | 1886 | s: *S = &S.instance, |
test/behavior/tuple.zig-2| ... | @@ -579,8 +579,6 @@ test "comptime fields in tuple can be initialized" { | ... | @@ -579,8 +579,6 @@ test "comptime fields in tuple can be initialized" { |
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | test "tuple default values" { | 581 | test "tuple default values" { |
| 582 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 583 | |||
| 584 | const T = struct { | 582 | const T = struct { |
| 585 | usize, | 583 | usize, |
| 586 | usize = 123, | 584 | usize = 123, |
test/behavior/union.zig-5| ... | @@ -1744,7 +1744,6 @@ test "union with 128 bit integer" { | ... | @@ -1744,7 +1744,6 @@ test "union with 128 bit integer" { |
| 1744 | 1744 | ||
| 1745 | test "memset extern union" { | 1745 | test "memset extern union" { |
| 1746 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1746 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1747 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1748 | 1747 | ||
| 1749 | const U = extern union { | 1748 | const U = extern union { |
| 1750 | foo: u8, | 1749 | foo: u8, |
| ... | @@ -1766,7 +1765,6 @@ test "memset extern union" { | ... | @@ -1766,7 +1765,6 @@ test "memset extern union" { |
| 1766 | 1765 | ||
| 1767 | test "memset packed union" { | 1766 | test "memset packed union" { |
| 1768 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1767 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1769 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1770 | 1768 | ||
| 1771 | const U = packed union { | 1769 | const U = packed union { |
| 1772 | a: u32, | 1770 | a: u32, |
| ... | @@ -1977,8 +1975,6 @@ test "reinterpret packed union inside packed struct" { | ... | @@ -1977,8 +1975,6 @@ test "reinterpret packed union inside packed struct" { |
| 1977 | } | 1975 | } |
| 1978 | 1976 | ||
| 1979 | test "inner struct initializer uses union layout" { | 1977 | test "inner struct initializer uses union layout" { |
| 1980 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1981 | |||
| 1982 | const namespace = struct { | 1978 | const namespace = struct { |
| 1983 | const U = union { | 1979 | const U = union { |
| 1984 | a: struct { | 1980 | a: struct { |
| ... | @@ -2004,7 +2000,6 @@ test "inner struct initializer uses union layout" { | ... | @@ -2004,7 +2000,6 @@ test "inner struct initializer uses union layout" { |
| 2004 | 2000 | ||
| 2005 | test "inner struct initializer uses packed union layout" { | 2001 | test "inner struct initializer uses packed union layout" { |
| 2006 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 2002 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 2007 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 2008 | 2003 | ||
| 2009 | const namespace = struct { | 2004 | const namespace = struct { |
| 2010 | const U = packed union { | 2005 | const U = packed union { |