authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-05-25 22:52:26-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-06-13 02:22:33-07:00
loga270c6f8c82bc81eecf37cc06a326e46ed44fb8b
tree6ee1ab61e42d94d92eaeb62ee7b371d64de2e9a7
parentd69c48370a0381c7dce463c68b2097dd8fa67eb7
signaturelock-open Commit is signed but in an unrecognized format.

riscv: implement optional logic


23 files changed, 222 insertions(+), 105 deletions(-)

src/arch/riscv64/CodeGen.zig+220-58
......@@ -1545,6 +1545,58 @@ fn splitType(func: *Func, ty: Type) ![2]Type {
15451545 return func.fail("TODO implement splitType for {}", .{ty.fmt(zcu)});
15461546}
15471547
1548/// Truncates the value in the register in place.
1549/// Clobbers any remaining bits.
1550fn truncateRegister(func: *Func, ty: Type, reg: Register) !void {
1551 const mod = func.bin_file.comp.module.?;
1552 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
1553 .signedness = .unsigned,
1554 .bits = @intCast(ty.bitSize(mod)),
1555 };
1556 const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return;
1557 switch (int_info.signedness) {
1558 .signed => {
1559 _ = try func.addInst(.{
1560 .tag = .slli,
1561 .ops = .rri,
1562 .data = .{
1563 .i_type = .{
1564 .rd = reg,
1565 .rs1 = reg,
1566 .imm12 = Immediate.s(shift),
1567 },
1568 },
1569 });
1570 _ = try func.addInst(.{
1571 .tag = .srai,
1572 .ops = .rri,
1573 .data = .{
1574 .i_type = .{
1575 .rd = reg,
1576 .rs1 = reg,
1577 .imm12 = Immediate.s(shift),
1578 },
1579 },
1580 });
1581 },
1582 .unsigned => {
1583 const mask = ~@as(u64, 0) >> shift;
1584 const tmp_reg = try func.copyToTmpRegister(Type.usize, .{ .immediate = mask });
1585 _ = try func.addInst(.{
1586 .tag = .@"and",
1587 .ops = .rrr,
1588 .data = .{
1589 .r_type = .{
1590 .rd = reg,
1591 .rs1 = reg,
1592 .rs2 = tmp_reg,
1593 },
1594 },
1595 });
1596 },
1597 }
1598}
1599
15481600fn symbolIndex(func: *Func) !u32 {
15491601 const zcu = func.bin_file.comp.module.?;
15501602 const decl_index = zcu.funcOwnerDeclIndex(func.func_index);
......@@ -2868,8 +2920,25 @@ fn airShr(func: *Func, inst: Air.Inst.Index) !void {
28682920}
28692921
28702922fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {
2923 const zcu = func.bin_file.comp.module.?;
28712924 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2872 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement .optional_payload for {}", .{func.target.cpu.arch});
2925 const result: MCValue = result: {
2926 const pl_ty = func.typeOfIndex(inst);
2927 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
2928
2929 const opt_mcv = try func.resolveInst(ty_op.operand);
2930 if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
2931 switch (opt_mcv) {
2932 .register => |pl_reg| try func.truncateRegister(pl_ty, pl_reg),
2933 else => {},
2934 }
2935 break :result opt_mcv;
2936 }
2937
2938 const pl_mcv = try func.allocRegOrMem(inst, true);
2939 try func.genCopy(pl_ty, pl_mcv, opt_mcv);
2940 break :result pl_mcv;
2941 };
28732942 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
28742943}
28752944
......@@ -3022,16 +3091,40 @@ fn airSaveErrReturnTraceIndex(func: *Func, inst: Air.Inst.Index) !void {
30223091}
30233092
30243093fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {
3094 const zcu = func.bin_file.comp.module.?;
30253095 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3026 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
3027 const zcu = func.bin_file.comp.module.?;
3028 const optional_ty = func.typeOfIndex(inst);
3096 const result: MCValue = result: {
3097 const pl_ty = func.typeOf(ty_op.operand);
3098 if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 };
30293099
3030 // Optional with a zero-bit payload type is just a boolean true
3031 if (optional_ty.abiSize(zcu) == 1)
3032 break :result MCValue{ .immediate = 1 };
3100 const opt_ty = func.typeOfIndex(inst);
3101 const pl_mcv = try func.resolveInst(ty_op.operand);
3102 const same_repr = opt_ty.optionalReprIsPayload(zcu);
3103 if (same_repr and func.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;
30333104
3034 return func.fail("TODO implement wrap optional for {}", .{func.target.cpu.arch});
3105 const pl_lock: ?RegisterLock = switch (pl_mcv) {
3106 .register => |reg| func.register_manager.lockRegAssumeUnused(reg),
3107 else => null,
3108 };
3109 defer if (pl_lock) |lock| func.register_manager.unlockReg(lock);
3110
3111 const opt_mcv = try func.allocRegOrMem(inst, true);
3112 try func.genCopy(pl_ty, opt_mcv, pl_mcv);
3113
3114 if (!same_repr) {
3115 const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu));
3116 switch (opt_mcv) {
3117 .load_frame => |frame_addr| try func.genSetMem(
3118 .{ .frame = frame_addr.index },
3119 frame_addr.off + pl_abi_size,
3120 Type.u8,
3121 .{ .immediate = 1 },
3122 ),
3123 .register => return func.fail("TODO: airWrapOption opt_mcv register", .{}),
3124 else => unreachable,
3125 }
3126 }
3127 break :result opt_mcv;
30353128 };
30363129 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
30373130}
......@@ -4435,72 +4528,141 @@ fn condBr(func: *Func, cond_ty: Type, condition: MCValue) !Mir.Inst.Index {
44354528 });
44364529}
44374530
4531fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
4532 const zcu = func.bin_file.comp.module.?;
4533 const pl_ty = opt_ty.optionalChild(zcu);
4534
4535 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu))
4536 .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty }
4537 else
4538 .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool };
4539
4540 const return_mcv = try func.allocRegOrMem(inst, true);
4541 assert(return_mcv == .register); // should not be larger 8 bytes
4542 const return_reg = return_mcv.register;
4543
4544 switch (opt_mcv) {
4545 .none,
4546 .unreach,
4547 .dead,
4548 .undef,
4549 .immediate,
4550 .register_pair,
4551 .register_offset,
4552 .lea_frame,
4553 .lea_symbol,
4554 .reserved_frame,
4555 .air_ref,
4556 => return func.fail("TODO: hmm {}", .{opt_mcv}),
4557
4558 .register => |opt_reg| {
4559 if (some_info.off == 0) {
4560 _ = try func.addInst(.{
4561 .tag = .pseudo,
4562 .ops = .pseudo_compare,
4563 .data = .{
4564 .compare = .{
4565 .op = .eq,
4566 .rd = return_reg,
4567 .rs1 = opt_reg,
4568 .rs2 = try func.copyToTmpRegister(
4569 some_info.ty,
4570 .{ .immediate = 0 },
4571 ),
4572 .size = .byte,
4573 },
4574 },
4575 });
4576 return return_mcv;
4577 }
4578 assert(some_info.ty.ip_index == .bool_type);
4579 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(zcu));
4580 _ = opt_abi_size;
4581 return func.fail("TODO: isNull some_info.off != 0 register", .{});
4582 },
4583
4584 .load_frame => {
4585 const opt_reg = try func.copyToTmpRegister(
4586 some_info.ty,
4587 opt_mcv.address().offset(some_info.off).deref(),
4588 );
4589 const opt_reg_lock = func.register_manager.lockRegAssumeUnused(opt_reg);
4590 defer func.register_manager.unlockReg(opt_reg_lock);
4591
4592 _ = try func.addInst(.{
4593 .tag = .pseudo,
4594 .ops = .pseudo_compare,
4595 .data = .{
4596 .compare = .{
4597 .op = .eq,
4598 .rd = return_reg,
4599 .rs1 = opt_reg,
4600 .rs2 = try func.copyToTmpRegister(
4601 some_info.ty,
4602 .{ .immediate = 0 },
4603 ),
4604 .size = .byte,
4605 },
4606 },
4607 });
4608 return return_mcv;
4609 },
4610
4611 else => return func.fail("TODO: isNull {}", .{opt_mcv}),
4612 }
4613}
4614
44384615fn airIsNull(func: *Func, inst: Air.Inst.Index) !void {
44394616 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4440 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4441 const operand = try func.resolveInst(un_op);
4442 break :result try func.isNull(operand);
4443 };
4617 const operand = try func.resolveInst(un_op);
4618 const ty = func.typeOf(un_op);
4619 const result = try func.isNull(inst, ty, operand);
44444620 return func.finishAir(inst, result, .{ un_op, .none, .none });
44454621}
44464622
44474623fn airIsNullPtr(func: *Func, inst: Air.Inst.Index) !void {
44484624 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4449 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4450 const operand_ptr = try func.resolveInst(un_op);
4451 const operand: MCValue = blk: {
4452 if (func.reuseOperand(inst, un_op, 0, operand_ptr)) {
4453 // The MCValue that holds the pointer can be re-used as the value.
4454 break :blk operand_ptr;
4455 } else {
4456 break :blk try func.allocRegOrMem(inst, true);
4457 }
4458 };
4459 try func.load(operand, operand_ptr, func.typeOf(un_op));
4460 break :result try func.isNull(operand);
4461 };
4462 return func.finishAir(inst, result, .{ un_op, .none, .none });
4463}
4625 const operand = try func.resolveInst(un_op);
4626 _ = operand; // autofix
4627 const ty = func.typeOf(un_op);
4628 _ = ty; // autofix
44644629
4465fn isNull(func: *Func, operand: MCValue) !MCValue {
4466 _ = operand;
4467 // Here you can specialize this instruction if it makes sense to, otherwise the default
4468 // will call isNonNull and invert the result.
4469 return func.fail("TODO call isNonNull and invert the result", .{});
4630 if (true) return func.fail("TODO: airIsNullPtr", .{});
4631
4632 return func.finishAir(inst, .unreach, .{ un_op, .none, .none });
44704633}
44714634
44724635fn airIsNonNull(func: *Func, inst: Air.Inst.Index) !void {
44734636 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4474 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4475 const operand = try func.resolveInst(un_op);
4476 break :result try func.isNonNull(operand);
4477 };
4478 return func.finishAir(inst, result, .{ un_op, .none, .none });
4479}
4637 const operand = try func.resolveInst(un_op);
4638 const ty = func.typeOf(un_op);
4639 const result = try func.isNull(inst, ty, operand);
4640 assert(result == .register);
44804641
4481fn isNonNull(func: *Func, operand: MCValue) !MCValue {
4482 _ = operand;
4483 // Here you can specialize this instruction if it makes sense to, otherwise the default
4484 // will call isNull and invert the result.
4485 return func.fail("TODO call isNull and invert the result", .{});
4642 _ = try func.addInst(.{
4643 .tag = .pseudo,
4644 .ops = .pseudo_not,
4645 .data = .{
4646 .rr = .{
4647 .rd = result.register,
4648 .rs = result.register,
4649 },
4650 },
4651 });
4652
4653 return func.finishAir(inst, result, .{ un_op, .none, .none });
44864654}
44874655
44884656fn airIsNonNullPtr(func: *Func, inst: Air.Inst.Index) !void {
44894657 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4490 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
4491 const operand_ptr = try func.resolveInst(un_op);
4492 const operand: MCValue = blk: {
4493 if (func.reuseOperand(inst, un_op, 0, operand_ptr)) {
4494 // The MCValue that holds the pointer can be re-used as the value.
4495 break :blk operand_ptr;
4496 } else {
4497 break :blk try func.allocRegOrMem(inst, true);
4498 }
4499 };
4500 try func.load(operand, operand_ptr, func.typeOf(un_op));
4501 break :result try func.isNonNull(operand);
4502 };
4503 return func.finishAir(inst, result, .{ un_op, .none, .none });
4658 const operand = try func.resolveInst(un_op);
4659 _ = operand; // autofix
4660 const ty = func.typeOf(un_op);
4661 _ = ty; // autofix
4662
4663 if (true) return func.fail("TODO: airIsNonNullPtr", .{});
4664
4665 return func.finishAir(inst, .unreach, .{ un_op, .none, .none });
45044666}
45054667
45064668fn airIsErr(func: *Func, inst: Air.Inst.Index) !void {
......@@ -5110,7 +5272,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
51105272 dst_mcv,
51115273 try func.resolveInst(src_ref),
51125274 ),
5113 else => unreachable,
5275 else => return func.fail("genCopy register_pair src: {}", .{src_mcv}),
51145276 };
51155277
51165278 defer if (src_info) |info| {
src/arch/riscv64/abi.zig+1
......@@ -125,6 +125,7 @@ pub fn classifySystem(ty: Type, zcu: *Module) [8]SystemClass {
125125 return result;
126126 }
127127 result[0] = .integer;
128 if (ty.optionalChild(zcu).abiSize(zcu) == 0) return result;
128129 result[1] = .integer;
129130 return result;
130131 },
src/arch/riscv64/bits.zig+1-1
......@@ -230,7 +230,7 @@ pub const Register = enum(u8) {
230230 return @as(u8, reg.id());
231231 }
232232
233 pub fn bitSize(reg: Register, zcu: Module) u32 {
233 pub fn bitSize(reg: Register, zcu: *const Module) u32 {
234234 const features = zcu.getTarget().cpu.features;
235235
236236 return switch (@intFromEnum(reg)) {
test/behavior/align.zig-1
......@@ -603,7 +603,6 @@ test "comptime alloc alignment" {
603603}
604604
605605test "@alignCast null" {
606 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
607606 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
608607 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
609608
test/behavior/basic.zig-2
......@@ -483,7 +483,6 @@ fn testStructInFn() !void {
483483
484484test "fn call returning scalar optional in equality expression" {
485485 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
486 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
487486 try expect(getNull() == null);
488487}
489488
......@@ -494,7 +493,6 @@ fn getNull() ?*i32 {
494493test "global variable assignment with optional unwrapping with var initialized to undefined" {
495494 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
496495 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
497 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
498496
499497 const S = struct {
500498 var data: i32 = 1234;
test/behavior/cast.zig-15
......@@ -186,7 +186,6 @@ fn expectIntFromFloat(comptime F: type, f: F, comptime I: type, i: I) !void {
186186test "implicitly cast indirect pointer to maybe-indirect pointer" {
187187 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
188188 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
189 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
190189
191190 const S = struct {
192191 const Self = @This();
......@@ -247,7 +246,6 @@ test "coerce undefined to optional" {
247246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
248247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
249248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
250 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
251249
252250 try expect(MakeType(void).getNull() == null);
253251 try expect(MakeType(void).getNonNull() != null);
......@@ -1184,7 +1182,6 @@ test "implicit ptr to *anyopaque" {
11841182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11851183 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11861184 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1187 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11881185
11891186 var a: u32 = 1;
11901187 const ptr: *align(@alignOf(u32)) anyopaque = &a;
......@@ -1198,7 +1195,6 @@ test "implicit ptr to *anyopaque" {
11981195test "return null from fn () anyerror!?&T" {
11991196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12001197 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1201 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12021198
12031199 const a = returnNullFromOptionalTypeErrorRef();
12041200 const b = returnNullLitFromOptionalTypeErrorRef();
......@@ -1289,7 +1285,6 @@ test "implicit cast from *T to ?*anyopaque" {
12891285 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12901286 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12911287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1292 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12931288
12941289 var a: u8 = 1;
12951290 incrementVoidPtrValue(&a);
......@@ -1361,7 +1356,6 @@ test "assignment to optional pointer result loc" {
13611356 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
13621357 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13631358 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1364 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13651359
13661360 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
13671361 _ = &foo;
......@@ -1437,7 +1431,6 @@ test "peer type resolution: unreachable, null, slice" {
14371431 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
14381432 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14391433 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1440 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14411434
14421435 const S = struct {
14431436 fn doTheTest(num: usize, word: []const u8) !void {
......@@ -1478,7 +1471,6 @@ test "cast compatible optional types" {
14781471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14791472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14801473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1481 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14821474
14831475 var a: ?[:0]const u8 = null;
14841476 _ = &a;
......@@ -1591,7 +1583,6 @@ test "bitcast packed struct with u0" {
15911583
15921584test "optional pointer coerced to optional allowzero pointer" {
15931585 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1594 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15951586
15961587 var p: ?*u32 = undefined;
15971588 var q: ?*allowzero u32 = undefined;
......@@ -1608,8 +1599,6 @@ test "optional slice coerced to allowzero many pointer" {
16081599}
16091600
16101601test "optional slice passed as parameter coerced to allowzero many pointer" {
1611 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1612
16131602 const ns = struct {
16141603 const Color = struct {
16151604 r: u8,
......@@ -1832,7 +1821,6 @@ test "peer type resolution: error union and optional of same type" {
18321821 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18331822 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18341823 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1835 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18361824
18371825 const E = error{Foo};
18381826 var a: E!*u8 = error.Foo;
......@@ -1878,7 +1866,6 @@ test "peer type resolution: three-way resolution combines error set and optional
18781866 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18791867 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18801868 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1881 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18821869
18831870 const E = error{Foo};
18841871 var a: E = error.Foo;
......@@ -2104,7 +2091,6 @@ test "peer type resolution: tuple pointer and optional slice" {
21042091 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21052092 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21062093 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21082094 // Miscompilation on Intel's OpenCL CPU runtime.
21092095 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
21102096
......@@ -2389,7 +2375,6 @@ test "cast builtins can wrap result in error union and optional" {
23892375 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
23902376 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23912377 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2392 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23932378
23942379 const S = struct {
23952380 const MyEnum = enum(u32) { _ };
test/behavior/error.zig-1
......@@ -124,7 +124,6 @@ test "debug info for optional error set" {
124124
125125test "implicit cast to optional to error union to return result loc" {
126126 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
128127
129128 const S = struct {
130129 fn entry() !void {
test/behavior/eval.zig-1
......@@ -1548,7 +1548,6 @@ test "non-optional and optional array elements concatenated" {
15481548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15491549 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15501550 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1551 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15521551
15531552 const array = [1]u8{'A'} ++ [1]?u8{null};
15541553 var index: usize = 0;
test/behavior/fn.zig-3
......@@ -104,7 +104,6 @@ test "inline function call that calls optional function pointer, return pointer
104104 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
105105 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
106106 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
108107
109108 const S = struct {
110109 field: u32,
......@@ -259,7 +258,6 @@ test "implicit cast fn call result to optional in field result" {
259258 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
260259 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
261260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
262 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
263261
264262 const S = struct {
265263 fn entry() !void {
......@@ -473,7 +471,6 @@ test "method call with optional and error union first param" {
473471test "method call with optional pointer first param" {
474472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
475473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
476 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
477474
478475 const S = struct {
479476 x: i32 = 1234,
test/behavior/generics.zig-1
......@@ -444,7 +444,6 @@ test "generic function passed as comptime argument" {
444444
445445test "return type of generic function is function pointer" {
446446 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
447 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
448447
449448 const S = struct {
450449 fn b(comptime T: type) ?*const fn () error{}!T {
test/behavior/if.zig-1
......@@ -139,7 +139,6 @@ test "if-else expression with runtime condition result location is inferred opti
139139 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
140140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
141141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
143142
144143 const A = struct { b: u64, c: u64 };
145144 var d: bool = true;
test/behavior/null.zig-3
......@@ -85,7 +85,6 @@ fn testTestNullRuntime(x: ?i32) !void {
8585test "optional void" {
8686 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8787 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8988
9089 try optionalVoidImpl();
9190 try comptime optionalVoidImpl();
......@@ -109,7 +108,6 @@ const Empty = struct {};
109108test "optional struct{}" {
110109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
111110 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
113111
114112 _ = try optionalEmptyStructImpl();
115113 _ = try comptime optionalEmptyStructImpl();
......@@ -135,7 +133,6 @@ test "null with default unwrap" {
135133
136134test "optional pointer to 0 bit type null value at runtime" {
137135 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
139136
140137 const EmptyStruct = struct {};
141138 var x: ?*EmptyStruct = null;
test/behavior/optional.zig-5
......@@ -29,7 +29,6 @@ pub const EmptyStruct = struct {};
2929
3030test "optional pointer to size zero struct" {
3131 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3332
3433 var e = EmptyStruct{};
3534 const o: ?*EmptyStruct = &e;
......@@ -60,7 +59,6 @@ fn testNullPtrsEql() !void {
6059test "optional with zero-bit type" {
6160 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
6261 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
63 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6462 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6563
6664 const S = struct {
......@@ -241,7 +239,6 @@ test "compare optionals with modified payloads" {
241239test "unwrap function call with optional pointer return value" {
242240 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
243241 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
244 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
245242
246243 const S = struct {
247244 fn entry() !void {
......@@ -373,7 +370,6 @@ test "0-bit child type coerced to optional return ptr result location" {
373370test "0-bit child type coerced to optional" {
374371 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
375372 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
376 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
377373
378374 const S = struct {
379375 fn doTheTest() !void {
......@@ -638,7 +634,6 @@ test "result location initialization of optional with OPV payload" {
638634 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
639635 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
640636 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
641 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
642637 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
643638
644639 const S = struct {
test/behavior/pointers.zig-2
......@@ -174,7 +174,6 @@ test "implicit cast error unions with non-optional to optional pointer" {
174174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
175175 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
176176 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
177 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
178177
179178 const S = struct {
180179 fn doTheTest() !void {
......@@ -222,7 +221,6 @@ test "assign null directly to C pointer and test null equality" {
222221 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
223222 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
224223 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
226224
227225 var x: [*c]i32 = null;
228226 _ = &x;
test/behavior/ptrfromint.zig-1
......@@ -34,7 +34,6 @@ test "@ptrFromInt creates null pointer" {
3434 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3535 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3636 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3837
3938 const ptr = @as(?*u32, @ptrFromInt(0));
4039 try expectEqual(@as(?*u32, null), ptr);
test/behavior/sizeof_and_typeof.zig-1
......@@ -328,7 +328,6 @@ test "peer type resolution with @TypeOf doesn't trigger dependency loop check" {
328328 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
329329 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
330330 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
331 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
332331
333332 const T = struct {
334333 next: @TypeOf(null, @as(*const @This(), undefined)),
test/behavior/slice.zig-1
......@@ -246,7 +246,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
246246test "C pointer" {
247247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
248248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
249 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
250249
251250 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
252251 var len: u32 = 10;
test/behavior/struct.zig-3
......@@ -1873,8 +1873,6 @@ test "initializer takes a pointer to a variable inside its struct" {
18731873}
18741874
18751875test "circular dependency through pointer field of a struct" {
1876 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1877
18781876 const S = struct {
18791877 const StructInner = extern struct {
18801878 outer: StructOuter = std.mem.zeroes(StructOuter),
......@@ -2151,7 +2149,6 @@ test "initiate global variable with runtime value" {
21512149test "struct containing optional pointer to array of @This()" {
21522150 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
21532151 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2154 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21552152
21562153 const S = struct {
21572154 x: ?*const [1]@This(),
test/behavior/struct_contains_null_ptr_itself.zig-1
......@@ -5,7 +5,6 @@ const builtin = @import("builtin");
55test "struct contains null pointer which contains original struct" {
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
77 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
98
109 var x: ?*NodeLineComment = null;
1110 _ = &x;
test/behavior/this.zig-1
......@@ -50,7 +50,6 @@ test "this used as optional function parameter" {
5050 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5151 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5252 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
53 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5453
5554 var global: State = undefined;
5655 global.enter = prev;
test/behavior/type.zig-1
......@@ -260,7 +260,6 @@ test "Type.Struct" {
260260 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
261261 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
262262 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
263 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
264263
265264 const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
266265 const infoA = @typeInfo(A).Struct;
test/behavior/union.zig-1
......@@ -2145,7 +2145,6 @@ test "pass register-sized field as non-register-sized union" {
21452145
21462146test "circular dependency through pointer field of a union" {
21472147 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2148 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21492148
21502149 const S = struct {
21512150 const UnionInner = extern struct {
test/behavior/void.zig-1
......@@ -37,7 +37,6 @@ test "void optional" {
3737 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3838 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3939 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
40 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4140
4241 var x: ?void = {};
4342 _ = &x;