| author | |
| committer | |
| log | 2fd83d8c0a8dd28c2474b26ead8cb24d6bde0901 |
| tree | c3293e36e9233a9c9e7ce4b4d56677173662ae9e |
| parent | a30af172e8dc360cb0a71a5c4dfd904120555715 |
15 files changed, 174 insertions(+), 35 deletions(-)
src/arch/riscv64/CodeGen.zig+89-10| ... | ... | @@ -1800,8 +1800,95 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1800 | 1800 | } |
| 1801 | 1801 | |
| 1802 | 1802 | fn airMin(self: *Self, inst: Air.Inst.Index) !void { |
| 1803 | const zcu = self.bin_file.comp.module.?; | |
| 1803 | 1804 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 1804 | const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement min for {}", .{self.target.cpu.arch}); | |
| 1805 | ||
| 1806 | const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: { | |
| 1807 | const lhs = try self.resolveInst(bin_op.lhs); | |
| 1808 | const rhs = try self.resolveInst(bin_op.rhs); | |
| 1809 | const lhs_ty = self.typeOf(bin_op.lhs); | |
| 1810 | const rhs_ty = self.typeOf(bin_op.rhs); | |
| 1811 | ||
| 1812 | const int_info = lhs_ty.intInfo(zcu); | |
| 1813 | ||
| 1814 | if (int_info.bits > 64) return self.fail("TODO: > 64 bit @min", .{}); | |
| 1815 | ||
| 1816 | const lhs_reg, const lhs_lock = blk: { | |
| 1817 | if (lhs == .register) break :blk .{ lhs.register, null }; | |
| 1818 | ||
| 1819 | const lhs_reg, const lhs_lock = try self.allocReg(); | |
| 1820 | try self.genSetReg(lhs_ty, lhs_reg, lhs); | |
| 1821 | break :blk .{ lhs_reg, lhs_lock }; | |
| 1822 | }; | |
| 1823 | defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); | |
| 1824 | ||
| 1825 | const rhs_reg, const rhs_lock = blk: { | |
| 1826 | if (rhs == .register) break :blk .{ rhs.register, null }; | |
| 1827 | ||
| 1828 | const rhs_reg, const rhs_lock = try self.allocReg(); | |
| 1829 | try self.genSetReg(rhs_ty, rhs_reg, rhs); | |
| 1830 | break :blk .{ rhs_reg, rhs_lock }; | |
| 1831 | }; | |
| 1832 | defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); | |
| 1833 | ||
| 1834 | const mask_reg, const mask_lock = try self.allocReg(); | |
| 1835 | defer self.register_manager.unlockReg(mask_lock); | |
| 1836 | ||
| 1837 | const result_reg, const result_lock = try self.allocReg(); | |
| 1838 | defer self.register_manager.unlockReg(result_lock); | |
| 1839 | ||
| 1840 | _ = try self.addInst(.{ | |
| 1841 | .tag = if (int_info.signedness == .unsigned) .sltu else .slt, | |
| 1842 | .ops = .rrr, | |
| 1843 | .data = .{ .r_type = .{ | |
| 1844 | .rd = mask_reg, | |
| 1845 | .rs1 = lhs_reg, | |
| 1846 | .rs2 = rhs_reg, | |
| 1847 | } }, | |
| 1848 | }); | |
| 1849 | ||
| 1850 | _ = try self.addInst(.{ | |
| 1851 | .tag = .sub, | |
| 1852 | .ops = .rrr, | |
| 1853 | .data = .{ .r_type = .{ | |
| 1854 | .rd = mask_reg, | |
| 1855 | .rs1 = .zero, | |
| 1856 | .rs2 = mask_reg, | |
| 1857 | } }, | |
| 1858 | }); | |
| 1859 | ||
| 1860 | _ = try self.addInst(.{ | |
| 1861 | .tag = .xor, | |
| 1862 | .ops = .rrr, | |
| 1863 | .data = .{ .r_type = .{ | |
| 1864 | .rd = result_reg, | |
| 1865 | .rs1 = lhs_reg, | |
| 1866 | .rs2 = rhs_reg, | |
| 1867 | } }, | |
| 1868 | }); | |
| 1869 | ||
| 1870 | _ = try self.addInst(.{ | |
| 1871 | .tag = .@"and", | |
| 1872 | .ops = .rrr, | |
| 1873 | .data = .{ .r_type = .{ | |
| 1874 | .rd = mask_reg, | |
| 1875 | .rs1 = result_reg, | |
| 1876 | .rs2 = mask_reg, | |
| 1877 | } }, | |
| 1878 | }); | |
| 1879 | ||
| 1880 | _ = try self.addInst(.{ | |
| 1881 | .tag = .xor, | |
| 1882 | .ops = .rrr, | |
| 1883 | .data = .{ .r_type = .{ | |
| 1884 | .rd = result_reg, | |
| 1885 | .rs1 = rhs_reg, | |
| 1886 | .rs2 = mask_reg, | |
| 1887 | } }, | |
| 1888 | }); | |
| 1889 | ||
| 1890 | break :result .{ .register = result_reg }; | |
| 1891 | }; | |
| 1805 | 1892 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1806 | 1893 | } |
| 1807 | 1894 | |
| ... | ... | @@ -3513,17 +3600,9 @@ fn genCall( |
| 3513 | 3600 | .imm12 = Immediate.s(0), |
| 3514 | 3601 | } }, |
| 3515 | 3602 | }); |
| 3516 | } else if (self.bin_file.cast(link.File.Coff)) |_| { | |
| 3517 | return self.fail("TODO implement calling in COFF for {}", .{self.target.cpu.arch}); | |
| 3518 | } else if (self.bin_file.cast(link.File.MachO)) |_| { | |
| 3519 | unreachable; // unsupported architecture for MachO | |
| 3520 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { | |
| 3521 | return self.fail("TODO implement call on plan9 for {}", .{self.target.cpu.arch}); | |
| 3522 | 3603 | } else unreachable; |
| 3523 | 3604 | }, |
| 3524 | .extern_func => { | |
| 3525 | return self.fail("TODO: extern func calls", .{}); | |
| 3526 | }, | |
| 3605 | .extern_func => return self.fail("TODO: extern func calls", .{}), | |
| 3527 | 3606 | else => return self.fail("TODO implement calling bitcasted functions", .{}), |
| 3528 | 3607 | } |
| 3529 | 3608 | } else { |
src/arch/riscv64/Encoding.zig+5-2| ... | ... | @@ -11,7 +11,6 @@ pub const Mnemonic = enum { |
| 11 | 11 | lb, |
| 12 | 12 | lbu, |
| 13 | 13 | sltiu, |
| 14 | sltu, | |
| 15 | 14 | xori, |
| 16 | 15 | andi, |
| 17 | 16 | slli, |
| ... | ... | @@ -38,9 +37,11 @@ pub const Mnemonic = enum { |
| 38 | 37 | |
| 39 | 38 | // R Type |
| 40 | 39 | add, |
| 40 | @"and", | |
| 41 | 41 | sub, |
| 42 | 42 | slt, |
| 43 | 43 | mul, |
| 44 | sltu, | |
| 44 | 45 | xor, |
| 45 | 46 | |
| 46 | 47 | // System |
| ... | ... | @@ -52,6 +53,8 @@ pub const Mnemonic = enum { |
| 52 | 53 | return switch (mnem) { |
| 53 | 54 | // zig fmt: off |
| 54 | 55 | .add => .{ .opcode = 0b0110011, .funct3 = 0b000, .funct7 = 0b0000000 }, |
| 56 | .sltu => .{ .opcode = 0b0110011, .funct3 = 0b011, .funct7 = 0b0000000 }, | |
| 57 | .@"and" => .{ .opcode = 0b0110011, .funct3 = 0b111, .funct7 = 0b0000000 }, | |
| 55 | 58 | .sub => .{ .opcode = 0b0110011, .funct3 = 0b000, .funct7 = 0b0100000 }, |
| 56 | 59 | |
| 57 | 60 | .ld => .{ .opcode = 0b0000011, .funct3 = 0b011, .funct7 = null }, |
| ... | ... | @@ -84,7 +87,6 @@ pub const Mnemonic = enum { |
| 84 | 87 | .beq => .{ .opcode = 0b1100011, .funct3 = 0b000, .funct7 = null }, |
| 85 | 88 | |
| 86 | 89 | .slt => .{ .opcode = 0b0110011, .funct3 = 0b010, .funct7 = 0b0000000 }, |
| 87 | .sltu => .{ .opcode = 0b0110011, .funct3 = 0b011, .funct7 = 0b0000000 }, | |
| 88 | 90 | |
| 89 | 91 | .xor => .{ .opcode = 0b0110011, .funct3 = 0b100, .funct7 = 0b0000000 }, |
| 90 | 92 | |
| ... | ... | @@ -149,6 +151,7 @@ pub const InstEnc = enum { |
| 149 | 151 | .xor, |
| 150 | 152 | .add, |
| 151 | 153 | .sub, |
| 154 | .@"and", | |
| 152 | 155 | => .R, |
| 153 | 156 | |
| 154 | 157 | .ecall, |
src/arch/riscv64/Mir.zig+6| ... | ... | @@ -32,6 +32,9 @@ pub const Inst = struct { |
| 32 | 32 | lui, |
| 33 | 33 | mv, |
| 34 | 34 | |
| 35 | @"and", | |
| 36 | xor, | |
| 37 | ||
| 35 | 38 | ebreak, |
| 36 | 39 | ecall, |
| 37 | 40 | unimp, |
| ... | ... | @@ -49,6 +52,9 @@ pub const Inst = struct { |
| 49 | 52 | /// Absolute Value, uses i_type payload. |
| 50 | 53 | abs, |
| 51 | 54 | |
| 55 | sltu, | |
| 56 | slt, | |
| 57 | ||
| 52 | 58 | /// Immediate Logical Right Shift, uses i_type payload |
| 53 | 59 | srli, |
| 54 | 60 | /// Immediate Logical Left Shift, uses i_type payload |
src/arch/riscv64/abi.zig+74-3| ... | ... | @@ -3,6 +3,7 @@ const bits = @import("bits.zig"); |
| 3 | 3 | const Register = bits.Register; |
| 4 | 4 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 5 | 5 | const Type = @import("../../type.zig").Type; |
| 6 | const InternPool = @import("../../InternPool.zig"); | |
| 6 | 7 | const Module = @import("../../Module.zig"); |
| 7 | 8 | const assert = std.debug.assert; |
| 8 | 9 | |
| ... | ... | @@ -97,7 +98,10 @@ pub fn classifyType(ty: Type, mod: *Module) Class { |
| 97 | 98 | pub fn classifySystem(ty: Type, zcu: *Module) [8]Class { |
| 98 | 99 | const ip = zcu.intern_pool; |
| 99 | 100 | var result = [1]Class{.none} ** 8; |
| 100 | ||
| 101 | const memory_class = [_]Class{ | |
| 102 | .memory, .none, .none, .none, | |
| 103 | .none, .none, .none, .none, | |
| 104 | }; | |
| 101 | 105 | switch (ty.zigTypeTag(zcu)) { |
| 102 | 106 | .Bool, .Void, .NoReturn => { |
| 103 | 107 | result[0] = .integer; |
| ... | ... | @@ -146,7 +150,12 @@ pub fn classifySystem(ty: Type, zcu: *Module) [8]Class { |
| 146 | 150 | // anyerror!void can fit into one register |
| 147 | 151 | if (payload_bits == 0) return result; |
| 148 | 152 | |
| 149 | std.debug.panic("support ErrorUnion payload {}", .{payload_ty.fmt(zcu)}); | |
| 153 | if (payload_bits <= 64) { | |
| 154 | result[1] = .integer; | |
| 155 | return result; | |
| 156 | } | |
| 157 | ||
| 158 | std.debug.panic("TODO: classifySystem ErrorUnion > 64 bit payload", .{}); | |
| 150 | 159 | }, |
| 151 | 160 | .Struct => { |
| 152 | 161 | const loaded_struct = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -158,13 +167,75 @@ pub fn classifySystem(ty: Type, zcu: *Module) [8]Class { |
| 158 | 167 | if (ty_size > 8) result[1] = .integer; |
| 159 | 168 | return result; |
| 160 | 169 | } |
| 170 | if (ty_size > 64) | |
| 171 | return memory_class; | |
| 161 | 172 | |
| 162 | std.debug.panic("support Struct in classifySystem", .{}); | |
| 173 | var byte_offset: u64 = 0; | |
| 174 | classifyStruct(&result, &byte_offset, loaded_struct, zcu); | |
| 175 | ||
| 176 | return result; | |
| 163 | 177 | }, |
| 164 | 178 | else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}), |
| 165 | 179 | } |
| 166 | 180 | } |
| 167 | 181 | |
| 182 | fn classifyStruct( | |
| 183 | result: *[8]Class, | |
| 184 | byte_offset: *u64, | |
| 185 | loaded_struct: InternPool.LoadedStructType, | |
| 186 | zcu: *Module, | |
| 187 | ) void { | |
| 188 | const ip = &zcu.intern_pool; | |
| 189 | var field_it = loaded_struct.iterateRuntimeOrder(ip); | |
| 190 | ||
| 191 | while (field_it.next()) |field_index| { | |
| 192 | const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); | |
| 193 | const field_align = loaded_struct.fieldAlign(ip, field_index); | |
| 194 | byte_offset.* = std.mem.alignForward( | |
| 195 | u64, | |
| 196 | byte_offset.*, | |
| 197 | field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?, | |
| 198 | ); | |
| 199 | if (zcu.typeToStruct(field_ty)) |field_loaded_struct| { | |
| 200 | if (field_loaded_struct.layout != .@"packed") { | |
| 201 | classifyStruct(result, byte_offset, field_loaded_struct, zcu); | |
| 202 | continue; | |
| 203 | } | |
| 204 | } | |
| 205 | const field_class = std.mem.sliceTo(&classifySystem(field_ty, zcu), .none); | |
| 206 | const field_size = field_ty.abiSize(zcu); | |
| 207 | ||
| 208 | combine: { | |
| 209 | const result_class = &result[@intCast(byte_offset.* / 8)]; | |
| 210 | if (result_class.* == field_class[0]) { | |
| 211 | break :combine; | |
| 212 | } | |
| 213 | ||
| 214 | if (result_class.* == .none) { | |
| 215 | result_class.* = field_class[0]; | |
| 216 | break :combine; | |
| 217 | } | |
| 218 | assert(field_class[0] != .none); | |
| 219 | ||
| 220 | // "If one of the classes is MEMORY, the result is the MEMORY class." | |
| 221 | if (result_class.* == .memory or field_class[0] == .memory) { | |
| 222 | result_class.* = .memory; | |
| 223 | break :combine; | |
| 224 | } | |
| 225 | ||
| 226 | // "If one of the classes is INTEGER, the result is the INTEGER." | |
| 227 | if (result_class.* == .integer or field_class[0] == .integer) { | |
| 228 | result_class.* = .integer; | |
| 229 | break :combine; | |
| 230 | } | |
| 231 | ||
| 232 | result_class.* = .integer; | |
| 233 | } | |
| 234 | @memcpy(result[@intCast(byte_offset.* / 8 + 1)..][0 .. field_class.len - 1], field_class[1..]); | |
| 235 | byte_offset.* += field_size; | |
| 236 | } | |
| 237 | } | |
| 238 | ||
| 168 | 239 | pub const callee_preserved_regs = [_]Register{ |
| 169 | 240 | // .s0 is ommited to be used as a frame pointer |
| 170 | 241 | .s1, .s2, .s3, .s4, .s5, .s6, .s7, .s8, .s9, .s10, .s11, |
test/behavior/array.zig-1| ... | ... | @@ -75,7 +75,6 @@ test "array concat with tuple" { |
| 75 | 75 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 76 | 76 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 77 | 77 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 78 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 79 | 78 | |
| 80 | 79 | const array: [2]u8 = .{ 1, 2 }; |
| 81 | 80 | { |
test/behavior/basic.zig-1| ... | ... | @@ -593,7 +593,6 @@ test "equality compare fn ptrs" { |
| 593 | 593 | |
| 594 | 594 | test "self reference through fn ptr field" { |
| 595 | 595 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 596 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 597 | 596 | |
| 598 | 597 | const S = struct { |
| 599 | 598 | const A = struct { |
test/behavior/cast.zig-2| ... | ... | @@ -2073,7 +2073,6 @@ test "peer type resolution: empty tuple pointer and slice" { |
| 2073 | 2073 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2074 | 2074 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2075 | 2075 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2076 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 2077 | 2076 | |
| 2078 | 2077 | var a: [:0]const u8 = "Hello"; |
| 2079 | 2078 | var b = &.{}; |
| ... | ... | @@ -2095,7 +2094,6 @@ test "peer type resolution: tuple pointer and slice" { |
| 2095 | 2094 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2096 | 2095 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2097 | 2096 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2098 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 2099 | 2097 | |
| 2100 | 2098 | var a: [:0]const u8 = "Hello"; |
| 2101 | 2099 | var b = &.{ @as(u8, 'x'), @as(u8, 'y'), @as(u8, 'z') }; |
test/behavior/fn.zig-3| ... | ... | @@ -191,7 +191,6 @@ test "function with complex callconv and return type expressions" { |
| 191 | 191 | |
| 192 | 192 | test "pass by non-copying value" { |
| 193 | 193 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 194 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 195 | 194 | |
| 196 | 195 | try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); |
| 197 | 196 | } |
| ... | ... | @@ -219,7 +218,6 @@ fn addPointCoordsVar(pt: anytype) !i32 { |
| 219 | 218 | |
| 220 | 219 | test "pass by non-copying value as method" { |
| 221 | 220 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 222 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 223 | 221 | |
| 224 | 222 | var pt = Point2{ .x = 1, .y = 2 }; |
| 225 | 223 | try expect(pt.addPointCoords() == 3); |
| ... | ... | @@ -236,7 +234,6 @@ const Point2 = struct { |
| 236 | 234 | |
| 237 | 235 | test "pass by non-copying value as method, which is generic" { |
| 238 | 236 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 239 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 240 | 237 | |
| 241 | 238 | var pt = Point3{ .x = 1, .y = 2 }; |
| 242 | 239 | try expect(pt.addPointCoords(i32) == 3); |
test/behavior/fn_delegation.zig-1| ... | ... | @@ -34,7 +34,6 @@ fn custom(comptime T: type, comptime num: u64) fn (T) u64 { |
| 34 | 34 | test "fn delegation" { |
| 35 | 35 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 36 | 36 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 37 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 38 | 37 | |
| 39 | 38 | const foo = Foo{}; |
| 40 | 39 | try expect(foo.one() == 11); |
test/behavior/generics.zig-1| ... | ... | @@ -395,7 +395,6 @@ test "extern function used as generic parameter" { |
| 395 | 395 | |
| 396 | 396 | test "generic struct as parameter type" { |
| 397 | 397 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 398 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 399 | 398 | |
| 400 | 399 | const S = struct { |
| 401 | 400 | fn doTheTest(comptime Int: type, thing: struct { int: Int }) !void { |
test/behavior/pointers.zig-1| ... | ... | @@ -434,7 +434,6 @@ test "indexing array with sentinel returns correct type" { |
| 434 | 434 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 435 | 435 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 436 | 436 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 437 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 438 | 437 | |
| 439 | 438 | var s: [:0]const u8 = "abc"; |
| 440 | 439 | try testing.expectEqualSlices(u8, "*const u8", @typeName(@TypeOf(&s[0]))); |
test/behavior/sizeof_and_typeof.zig-1| ... | ... | @@ -412,7 +412,6 @@ test "Extern function calls, dereferences and field access in @TypeOf" { |
| 412 | 412 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 413 | 413 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 414 | 414 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 415 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 416 | 415 | |
| 417 | 416 | const Test = struct { |
| 418 | 417 | fn test_fn_1(a: c_long) @TypeOf(c_fopen("test", "r").*) { |
test/behavior/slice.zig-1| ... | ... | @@ -939,7 +939,6 @@ test "modify slice length at comptime" { |
| 939 | 939 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 940 | 940 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 941 | 941 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 942 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 943 | 942 | |
| 944 | 943 | const arr: [2]u8 = .{ 10, 20 }; |
| 945 | 944 | comptime var s: []const u8 = arr[0..0]; |
test/behavior/struct.zig-7| ... | ... | @@ -176,7 +176,6 @@ const MemberFnTestFoo = struct { |
| 176 | 176 | |
| 177 | 177 | test "call member function directly" { |
| 178 | 178 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 179 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 180 | 179 | |
| 181 | 180 | const instance = MemberFnTestFoo{ .x = 1234 }; |
| 182 | 181 | const result = MemberFnTestFoo.member(instance); |
| ... | ... | @@ -185,7 +184,6 @@ test "call member function directly" { |
| 185 | 184 | |
| 186 | 185 | test "store member function in variable" { |
| 187 | 186 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 188 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 189 | 187 | |
| 190 | 188 | const instance = MemberFnTestFoo{ .x = 1234 }; |
| 191 | 189 | const memberFn = MemberFnTestFoo.member; |
| ... | ... | @@ -1561,7 +1559,6 @@ test "discarded struct initialization works as expected" { |
| 1561 | 1559 | test "function pointer in struct returns the struct" { |
| 1562 | 1560 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1563 | 1561 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1564 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1565 | 1562 | |
| 1566 | 1563 | const A = struct { |
| 1567 | 1564 | const A = @This(); |
| ... | ... | @@ -1784,8 +1781,6 @@ fn countFields(v: anytype) usize { |
| 1784 | 1781 | } |
| 1785 | 1782 | |
| 1786 | 1783 | test "struct init with no result pointer sets field result types" { |
| 1787 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1788 | ||
| 1789 | 1784 | const S = struct { |
| 1790 | 1785 | // A function parameter has a result type, but no result pointer. |
| 1791 | 1786 | fn f(s: struct { x: u32 }) u32 { |
| ... | ... | @@ -1933,8 +1928,6 @@ test "circular dependency through pointer field of a struct" { |
| 1933 | 1928 | } |
| 1934 | 1929 | |
| 1935 | 1930 | test "field calls do not force struct field init resolution" { |
| 1936 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 1937 | ||
| 1938 | 1931 | const S = struct { |
| 1939 | 1932 | x: u32 = blk: { |
| 1940 | 1933 | _ = @TypeOf(make().dummyFn()); // runtime field call - S not fully resolved - dummyFn call should not force field init resolution |
test/behavior/type.zig-1| ... | ... | @@ -203,7 +203,6 @@ test "Type.Opaque" { |
| 203 | 203 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 204 | 204 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 205 | 205 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 206 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 207 | 206 | |
| 208 | 207 | const Opaque = @Type(.{ |
| 209 | 208 | .Opaque = .{ |