authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-04-28 22:22:26-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-06-13 02:19:40-07:00
logc457f35da565e589071db9e55d0866f35cd095dc
tree45994b3380f17d187f65ed08a61bda4cfa99cac1
parentf34dcd067b6e9783a53f007746309bb1f635fbf0
signaturelock-open Commit is signed but in an unrecognized format.

riscv: arbitrary sized arrays


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 });
22742275
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 );
22842282
...@@ -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 );
22922290 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 );
23022296
...@@ -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 {
23402334
2341 const tuple_ty = self.typeOfIndex(inst);2335 const tuple_ty = self.typeOfIndex(inst);
23422336
2343 // TODO: optimization, set this to true. needs the other struct access stuff to support2337 const result_mcv = try self.allocRegOrMem(inst, true);
2344 // accessing registers.
2345 const result_mcv = try self.allocRegOrMem(inst, false);
23462338
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));
23492341
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 );
23512347
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 );
23872383
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 );
23932389
...@@ -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}
28922888
2893fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {2889fn 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}
28992934
...@@ -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 },
45684603 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}
46194650
4620fn 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
4702fn genInlineMemcpy(4651fn 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}
48074756
4757fn 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.
4809fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void {4838fn 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 };
49704999
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}
50005029
5030fn 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
5001fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {5150fn 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}
51005249
5101fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {5250fn 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 dest5253
5105 } else {5254 result: {
5106 // TODO if the value is undef, don't lower this instruction5255 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}
51105329
5111fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {5330fn 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 }
51975437
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;
52005462
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);
52045466 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 };
52205473
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 {
169169
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 {
3535
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) {
149149
150pub const Register = enum(u6) {150pub const Register = enum(u6) {
151 // zig fmt: off151 // 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,
156154
157 zero, // zero155 zero, // zero
158 ra, // return address. caller saved156 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 saved166 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: on174 // zig fmt: on
170175
171 /// Returns the unique 5-bit ID of this register which is used in176 /// 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};
181192
182pub const FrameIndex = enum(u32) {193pub 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}
3030
31test "correct alignment for elements and slices of aligned array" {31test "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" {
231test "implicit comptime in array type size" {231test "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; // TODO233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
234 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
235234
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" {
505test "access the null element of a null terminated array" {504test "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; // TODO506 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
509507
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}
779777
780test "array init with no result pointer sets field result types" {778test "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; // TODO1695 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1696 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1696 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1697 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1697 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1698 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16991698
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; // TODO1865 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1867 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1866 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1868 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1867 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1869 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18701868
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; // TODO2238 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO2239 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2242 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2240 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2243 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
22442241
2245 var buf = "hello".*;2242 var buf = "hello".*;
22462243
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 {
73test "constant expressions" {73test "constant expressions" {
74 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO74 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
75 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO75 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7776
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;
2423
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;
3836
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}
415415
416test "function with inferred error set but returning no error" {416test "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; // TODO487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
488 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO488 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
489 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO489 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
490 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
491490
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; // TODO119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
120 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
121120
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; // TODO300 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
301 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO301 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
302 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO302 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 and303 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;
306305
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; // TODO77 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;
8079
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;
7776
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;
9088
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;
104101
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; // TODO435 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 access437 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 yet438 if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet
440439
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 {
58test "reinterpret bytes of an array into an extern struct" {58test "reinterpret bytes of an array into an extern struct" {
59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6261
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; // TODO49 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5150
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; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO11 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;
1413
15 _ = retAddr();14 _ = retAddr();
16 // TODO: #1493815 // 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 {
111111
112test "struct byval assign" {112test "struct byval assign" {
113 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO113 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
114 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
115114
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 {
300test "struct point to self" {299test "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; // TODO301 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
303 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
304302
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; // TODO1021 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1024 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1022 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1025 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1023 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1026 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10271024
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; // TODO1729 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1733 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1730 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1734 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1731 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1735 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17361732
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}
18641860
1865test "initializer uses own alignment" {1861test "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}
18771871
1878test "initializer uses own size" {1872test "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}
18901882
1891test "initializer takes a pointer to a variable inside its struct" {1883test "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}
580580
581test "tuple default values" {581test "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" {
17441744
1745test "memset extern union" {1745test "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;
17481747
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" {
17661765
1767test "memset packed union" {1766test "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;
17701768
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}
19781976
1979test "inner struct initializer uses union layout" {1977test "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" {
20042000
2005test "inner struct initializer uses packed union layout" {2001test "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;
20082003
2009 const namespace = struct {2004 const namespace = struct {
2010 const U = packed union {2005 const U = packed union {