authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-11 21:35:18+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-05-11 21:35:18+02:00
log86d8688c7f14d30c66b2cb4b55826ab15b39ad55
treefb6e98b216a383cab98ceeb5931564401eb9dd60
parent661a9be66bdee78530e5a6fbb6463297a405beee
parent75372f12ef1301118eed33e429f7498e76836cb3
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19431 from Rexicon226/revive-riscv

revive STAGE2 RISCV64 backend

135 files changed, 6570 insertions(+), 1660 deletions(-)

lib/compiler/test_runner.zig+18
......@@ -12,6 +12,8 @@ var cmdline_buffer: [4096]u8 = undefined;
1212var fba = std.heap.FixedBufferAllocator.init(&cmdline_buffer);
1313
1414pub fn main() void {
15 if (builtin.zig_backend == .stage2_riscv64) return mainExtraSimple() catch @panic("test failure");
16
1517 if (builtin.zig_backend == .stage2_aarch64) {
1618 return mainSimple() catch @panic("test failure");
1719 }
......@@ -247,3 +249,19 @@ pub fn mainSimple() anyerror!void {
247249 if (failed != 0) std.process.exit(1);
248250 }
249251}
252
253pub fn mainExtraSimple() !void {
254 var fail_count: u8 = 0;
255
256 for (builtin.test_functions) |test_fn| {
257 test_fn.func() catch |err| {
258 if (err != error.SkipZigTest) {
259 fail_count += 1;
260 continue;
261 }
262 continue;
263 };
264 }
265
266 if (fail_count != 0) std.process.exit(1);
267}
lib/std/builtin.zig+13-1
......@@ -766,7 +766,6 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
766766 builtin.zig_backend == .stage2_aarch64 or
767767 builtin.zig_backend == .stage2_x86 or
768768 (builtin.zig_backend == .stage2_x86_64 and (builtin.target.ofmt != .elf and builtin.target.ofmt != .macho)) or
769 builtin.zig_backend == .stage2_riscv64 or
770769 builtin.zig_backend == .stage2_sparc64 or
771770 builtin.zig_backend == .stage2_spirv64)
772771 {
......@@ -774,6 +773,19 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
774773 @breakpoint();
775774 }
776775 }
776
777 if (builtin.zig_backend == .stage2_riscv64) {
778 asm volatile ("ecall"
779 :
780 : [number] "{a7}" (64),
781 [arg1] "{a0}" (1),
782 [arg2] "{a1}" (@intFromPtr(msg.ptr)),
783 [arg3] "{a2}" (msg.len),
784 : "memory"
785 );
786 std.posix.exit(127);
787 }
788
777789 switch (builtin.os.tag) {
778790 .freestanding => {
779791 while (true) {
lib/std/dwarf.zig+1-9
......@@ -1236,15 +1236,7 @@ pub const DwarfInfo = struct {
12361236
12371237 const opcode_base = try fbr.readByte();
12381238
1239 const standard_opcode_lengths = try allocator.alloc(u8, opcode_base - 1);
1240 defer allocator.free(standard_opcode_lengths);
1241
1242 {
1243 var i: usize = 0;
1244 while (i < opcode_base - 1) : (i += 1) {
1245 standard_opcode_lengths[i] = try fbr.readByte();
1246 }
1247 }
1239 const standard_opcode_lengths = try fbr.readBytes(opcode_base - 1);
12481240
12491241 var include_directories = std.ArrayList(FileEntry).init(allocator);
12501242 defer include_directories.deinit();
lib/std/mem.zig+2
......@@ -638,6 +638,8 @@ test lessThan {
638638const backend_can_use_eql_bytes = switch (builtin.zig_backend) {
639639 // The SPIR-V backend does not support the optimized path yet.
640640 .stage2_spirv64 => false,
641 // The RISC-V does not support vectors.
642 .stage2_riscv64 => false,
641643 else => true,
642644};
643645
lib/std/start.zig+23-10
......@@ -20,10 +20,10 @@ pub const simplified_logic =
2020 builtin.zig_backend == .stage2_x86 or
2121 builtin.zig_backend == .stage2_aarch64 or
2222 builtin.zig_backend == .stage2_arm or
23 builtin.zig_backend == .stage2_riscv64 or
2423 builtin.zig_backend == .stage2_sparc64 or
2524 builtin.cpu.arch == .spirv32 or
26 builtin.cpu.arch == .spirv64;
25 builtin.cpu.arch == .spirv64 or
26 builtin.zig_backend == .stage2_riscv64;
2727
2828comptime {
2929 // No matter what, we import the root file, so that any export, test, comptime
......@@ -43,6 +43,10 @@ comptime {
4343 } else if (builtin.os.tag == .opencl) {
4444 if (@hasDecl(root, "main"))
4545 @export(spirvMain2, .{ .name = "main" });
46 } else if (native_arch.isRISCV()) {
47 if (!@hasDecl(root, "_start")) {
48 @export(riscv_start, .{ .name = "_start" });
49 }
4650 } else {
4751 if (!@hasDecl(root, "_start")) {
4852 @export(_start2, .{ .name = "_start" });
......@@ -151,14 +155,6 @@ fn exit2(code: usize) noreturn {
151155 : "memory", "cc"
152156 );
153157 },
154 .riscv64 => {
155 asm volatile ("ecall"
156 :
157 : [number] "{a7}" (94),
158 [arg1] "{a0}" (0),
159 : "rcx", "r11", "memory"
160 );
161 },
162158 .sparc64 => {
163159 asm volatile ("ta 0x6d"
164160 :
......@@ -212,6 +208,23 @@ fn wasi_start() callconv(.C) void {
212208 }
213209}
214210
211fn riscv_start() callconv(.C) noreturn {
212 std.process.exit(switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) {
213 .NoReturn => root.main(),
214 .Void => ret: {
215 root.main();
216 break :ret 0;
217 },
218 .Int => |info| ret: {
219 if (info.bits != 8 or info.signedness == .signed) {
220 @compileError(bad_main_ret);
221 }
222 break :ret root.main();
223 },
224 else => @compileError("expected return type of main to be 'void', 'noreturn', 'u8'"),
225 });
226}
227
215228fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv(.C) usize {
216229 uefi.handle = handle;
217230 uefi.system_table = system_table;
lib/std/testing.zig+1-1
......@@ -22,7 +22,7 @@ pub var base_allocator_instance = std.heap.FixedBufferAllocator.init("");
2222pub var log_level = std.log.Level.warn;
2323
2424// Disable printing in tests for simple backends.
25pub const backend_can_print = builtin.zig_backend != .stage2_spirv64;
25pub const backend_can_print = !(builtin.zig_backend == .stage2_spirv64 or builtin.zig_backend == .stage2_riscv64);
2626
2727fn print(comptime fmt: []const u8, args: anytype) void {
2828 if (@inComptime()) {
src/Sema.zig+4-3
......@@ -10499,9 +10499,10 @@ fn intCast(
1049910499 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_scalar_ty);
1050010500 const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar);
1050110501 const dest_max = Air.internedToRef(dest_max_val.toIntern());
10502 const diff = try block.addBinOp(.sub_wrap, dest_max, operand);
1050310502
1050410503 if (actual_info.signedness == .signed) {
10504 const diff = try block.addBinOp(.sub_wrap, dest_max, operand);
10505
1050510506 // Reinterpret the sign-bit as part of the value. This will make
1050610507 // negative differences (`operand` > `dest_max`) appear too big.
1050710508 const unsigned_scalar_operand_ty = try mod.intType(.unsigned, actual_bits);
......@@ -10542,7 +10543,7 @@ fn intCast(
1054210543 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
1054310544 } else {
1054410545 const ok = if (is_vector) ok: {
10545 const is_in_range = try block.addCmpVector(diff, dest_max, .lte);
10546 const is_in_range = try block.addCmpVector(operand, dest_max, .lte);
1054610547 const all_in_range = try block.addInst(.{
1054710548 .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
1054810549 .data = .{ .reduce = .{
......@@ -10552,7 +10553,7 @@ fn intCast(
1055210553 });
1055310554 break :ok all_in_range;
1055410555 } else ok: {
10555 const is_in_range = try block.addBinOp(.cmp_lte, diff, dest_max);
10556 const is_in_range = try block.addBinOp(.cmp_lte, operand, dest_max);
1055610557 break :ok is_in_range;
1055710558 };
1055810559 try sema.addSafetyCheck(block, src, ok, .cast_truncated_data);
src/arch/riscv64/CodeGen.zig+3584-963
......@@ -11,6 +11,7 @@ const Type = @import("../../type.zig").Type;
1111const Value = @import("../../Value.zig");
1212const link = @import("../../link.zig");
1313const Module = @import("../../Module.zig");
14const Package = @import("../../Package.zig");
1415const InternPool = @import("../../InternPool.zig");
1516const Compilation = @import("../../Compilation.zig");
1617const ErrorMsg = Module.ErrorMsg;
......@@ -19,7 +20,8 @@ const Allocator = mem.Allocator;
1920const trace = @import("../../tracy.zig").trace;
2021const DW = std.dwarf;
2122const leb128 = std.leb;
22const log = std.log.scoped(.codegen);
23const log = std.log.scoped(.riscv_codegen);
24const tracking_log = std.log.scoped(.tracking);
2325const build_options = @import("build_options");
2426const codegen = @import("../../codegen.zig");
2527const Alignment = InternPool.Alignment;
......@@ -31,16 +33,31 @@ const DebugInfoOutput = codegen.DebugInfoOutput;
3133const bits = @import("bits.zig");
3234const abi = @import("abi.zig");
3335const Register = bits.Register;
36const Immediate = bits.Immediate;
37const Memory = bits.Memory;
38const FrameIndex = bits.FrameIndex;
3439const RegisterManager = abi.RegisterManager;
3540const RegisterLock = RegisterManager.RegisterLock;
36const Instruction = abi.Instruction;
3741const callee_preserved_regs = abi.callee_preserved_regs;
42/// General Purpose
3843const gp = abi.RegisterClass.gp;
44/// Function Args
45const fa = abi.RegisterClass.fa;
46/// Function Returns
47const fr = abi.RegisterClass.fr;
48/// Temporary Use
49const tp = abi.RegisterClass.tp;
3950
4051const InnerError = CodeGenError || error{OutOfRegisters};
4152
53const RegisterView = enum(u1) {
54 caller,
55 callee,
56};
57
4258gpa: Allocator,
4359air: Air,
60mod: *Package.Module,
4461liveness: Liveness,
4562bin_file: *link.File,
4663target: *const std.Target,
......@@ -49,11 +66,10 @@ code: *std.ArrayList(u8),
4966debug_output: DebugInfoOutput,
5067err_msg: ?*ErrorMsg,
5168args: []MCValue,
52ret_mcv: MCValue,
69ret_mcv: InstTracking,
5370fn_type: Type,
5471arg_index: usize,
5572src_loc: Module.SrcLoc,
56stack_align: Alignment,
5773
5874/// MIR Instructions
5975mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
......@@ -64,6 +80,8 @@ mir_extra: std.ArrayListUnmanaged(u32) = .{},
6480end_di_line: u32,
6581end_di_column: u32,
6682
83scope_generation: u32,
84
6785/// The value is an offset into the `Function` `code` from the beginning.
6886/// To perform the reloc, write 32-bit signed little-endian integer
6987/// which is a relative jump, based on the address following the reloc.
......@@ -80,22 +98,24 @@ branch_stack: *std.ArrayList(Branch),
8098
8199// Key is the block instruction
82100blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .{},
83
84101register_manager: RegisterManager = .{},
85/// Maps offset to what is stored there.
86stack: std.AutoHashMapUnmanaged(u32, StackAllocation) = .{},
87102
88/// Offset from the stack base, representing the end of the stack frame.
89max_end_stack: u32 = 0,
90/// Represents the current end stack offset. If there is no existing slot
91/// to place a new stack allocation, it goes here, and then bumps `max_end_stack`.
92next_stack_offset: u32 = 0,
103const_tracking: ConstTrackingMap = .{},
104inst_tracking: InstTrackingMap = .{},
105
106frame_allocs: std.MultiArrayList(FrameAlloc) = .{},
107free_frame_indices: std.AutoArrayHashMapUnmanaged(FrameIndex, void) = .{},
108frame_locs: std.MultiArrayList(Mir.FrameLoc) = .{},
93109
94110/// Debug field, used to find bugs in the compiler.
95111air_bookkeeping: @TypeOf(air_bookkeeping_init) = air_bookkeeping_init,
96112
97113const air_bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {};
98114
115const SymbolOffset = struct { sym: u32, off: i32 = 0 };
116const RegisterOffset = struct { reg: Register, off: i32 = 0 };
117pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
118
99119const MCValue = union(enum) {
100120 /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc.
101121 /// TODO Look into deleting this tag and using `dead` instead, since every use
......@@ -104,26 +124,43 @@ const MCValue = union(enum) {
104124 /// Control flow will not allow this value to be observed.
105125 unreach,
106126 /// No more references to this value remain.
107 dead,
127 /// The payload is the value of scope_generation at the point where the death occurred
128 dead: u32,
108129 /// The value is undefined.
109130 undef,
110131 /// A pointer-sized integer that fits in a register.
111132 /// If the type is a pointer, this is the pointer address in virtual address space.
112133 immediate: u64,
134 /// The value doesn't exist in memory yet.
135 load_symbol: SymbolOffset,
136 /// The address of the memory location not-yet-allocated by the linker.
137 lea_symbol: SymbolOffset,
113138 /// The value is in a target-specific register.
114139 register: Register,
140 /// The value is split across two registers
141 register_pair: [2]Register,
115142 /// The value is in memory at a hard-coded address.
116143 /// If the type is a pointer, it means the pointer address is at this memory location.
117144 memory: u64,
118 /// The value is one of the stack variables.
119 /// If the type is a pointer, it means the pointer address is in the stack at this offset.
120 stack_offset: u32,
121 /// The value is a pointer to one of the stack variables (payload is stack offset).
122 ptr_stack_offset: u32,
145 /// The value stored at an offset from a frame index
146 /// Payload is a frame address.
147 load_frame: FrameAddr,
148 /// The address of an offset from a frame index
149 /// Payload is a frame address.
150 lea_frame: FrameAddr,
151 air_ref: Air.Inst.Ref,
152 /// The value is in memory at a constant offset from the address in a register.
153 indirect: RegisterOffset,
154 /// The value is a constant offset from the value in a register.
155 register_offset: RegisterOffset,
156 /// This indicates that we have already allocated a frame index for this instruction,
157 /// but it has not been spilled there yet in the current control flow.
158 /// Payload is a frame index.
159 reserved_frame: FrameIndex,
123160
124161 fn isMemory(mcv: MCValue) bool {
125162 return switch (mcv) {
126 .memory, .stack_offset => true,
163 .memory, .indirect, .load_frame => true,
127164 else => false,
128165 };
129166 }
......@@ -143,15 +180,116 @@ const MCValue = union(enum) {
143180
144181 .immediate,
145182 .memory,
146 .ptr_stack_offset,
183 .lea_frame,
147184 .undef,
185 .lea_symbol,
186 .air_ref,
187 .reserved_frame,
148188 => false,
149189
150190 .register,
151 .stack_offset,
191 .register_pair,
192 .register_offset,
193 .load_frame,
194 .load_symbol,
195 .indirect,
152196 => true,
153197 };
154198 }
199
200 fn address(mcv: MCValue) MCValue {
201 return switch (mcv) {
202 .none,
203 .unreach,
204 .dead,
205 .immediate,
206 .lea_frame,
207 .register_offset,
208 .register_pair,
209 .register,
210 .undef,
211 .air_ref,
212 .lea_symbol,
213 .reserved_frame,
214 => unreachable, // not in memory
215
216 .load_symbol => |sym_off| .{ .lea_symbol = sym_off },
217 .memory => |addr| .{ .immediate = addr },
218 .load_frame => |off| .{ .lea_frame = off },
219 .indirect => |reg_off| switch (reg_off.off) {
220 0 => .{ .register = reg_off.reg },
221 else => .{ .register_offset = reg_off },
222 },
223 };
224 }
225
226 fn deref(mcv: MCValue) MCValue {
227 return switch (mcv) {
228 .none,
229 .unreach,
230 .dead,
231 .memory,
232 .indirect,
233 .undef,
234 .air_ref,
235 .load_frame,
236 .register_pair,
237 .load_symbol,
238 .reserved_frame,
239 => unreachable, // not a pointer
240
241 .immediate => |addr| .{ .memory = addr },
242 .lea_frame => |off| .{ .load_frame = off },
243 .register => |reg| .{ .indirect = .{ .reg = reg } },
244 .register_offset => |reg_off| .{ .indirect = reg_off },
245 .lea_symbol => |sym_off| .{ .load_symbol = sym_off },
246 };
247 }
248
249 fn offset(mcv: MCValue, off: i32) MCValue {
250 return switch (mcv) {
251 .none,
252 .unreach,
253 .dead,
254 .undef,
255 .air_ref,
256 .reserved_frame,
257 => unreachable, // not valid
258 .register_pair,
259 .memory,
260 .indirect,
261 .load_frame,
262 .load_symbol,
263 .lea_symbol,
264 => switch (off) {
265 0 => mcv,
266 else => unreachable, // not offsettable
267 },
268 .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) },
269 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },
270 .register_offset => |reg_off| .{ .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off } },
271 .lea_frame => |frame_addr| .{
272 .lea_frame = .{ .index = frame_addr.index, .off = frame_addr.off + off },
273 },
274 };
275 }
276
277 fn getReg(mcv: MCValue) ?Register {
278 return switch (mcv) {
279 .register => |reg| reg,
280 .register_offset, .indirect => |ro| ro.reg,
281 else => null,
282 };
283 }
284
285 fn getRegs(mcv: *const MCValue) []const Register {
286 return switch (mcv.*) {
287 .register => |*reg| @as(*const [1]Register, reg),
288 .register_pair => |*regs| regs,
289 .register_offset, .indirect => |*ro| @as(*const [1]Register, &ro.reg),
290 else => &.{},
291 };
292 }
155293};
156294
157295const Branch = struct {
......@@ -163,60 +301,403 @@ const Branch = struct {
163301 }
164302};
165303
304const InstTrackingMap = std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InstTracking);
305const ConstTrackingMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, InstTracking);
306const InstTracking = struct {
307 long: MCValue,
308 short: MCValue,
309
310 fn init(result: MCValue) InstTracking {
311 return .{ .long = switch (result) {
312 .none,
313 .unreach,
314 .undef,
315 .immediate,
316 .memory,
317 .load_frame,
318 .lea_frame,
319 .load_symbol,
320 .lea_symbol,
321 => result,
322 .dead,
323 .reserved_frame,
324 .air_ref,
325 => unreachable,
326 .register,
327 .register_pair,
328 .register_offset,
329 .indirect,
330 => .none,
331 }, .short = result };
332 }
333
334 fn getReg(self: InstTracking) ?Register {
335 return self.short.getReg();
336 }
337
338 fn getRegs(self: *const InstTracking) []const Register {
339 return self.short.getRegs();
340 }
341
342 fn spill(self: *InstTracking, function: *Self, inst: Air.Inst.Index) !void {
343 if (std.meta.eql(self.long, self.short)) return; // Already spilled
344 // Allocate or reuse frame index
345 switch (self.long) {
346 .none => self.long = try function.allocRegOrMem(inst, false),
347 .load_frame => {},
348 .reserved_frame => |index| self.long = .{ .load_frame = .{ .index = index } },
349 else => unreachable,
350 }
351 tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long });
352 try function.genCopy(function.typeOfIndex(inst), self.long, self.short);
353 }
354
355 fn reuseFrame(self: *InstTracking) void {
356 switch (self.long) {
357 .reserved_frame => |index| self.long = .{ .load_frame = .{ .index = index } },
358 else => {},
359 }
360 self.short = switch (self.long) {
361 .none,
362 .unreach,
363 .undef,
364 .immediate,
365 .memory,
366 .load_frame,
367 .lea_frame,
368 .load_symbol,
369 .lea_symbol,
370 => self.long,
371 .dead,
372 .register,
373 .register_pair,
374 .register_offset,
375 .indirect,
376 .reserved_frame,
377 .air_ref,
378 => unreachable,
379 };
380 }
381
382 fn trackSpill(self: *InstTracking, function: *Self, inst: Air.Inst.Index) !void {
383 try function.freeValue(self.short);
384 self.reuseFrame();
385 tracking_log.debug("%{d} => {} (spilled)", .{ inst, self.* });
386 }
387
388 fn verifyMaterialize(self: InstTracking, target: InstTracking) void {
389 switch (self.long) {
390 .none,
391 .unreach,
392 .undef,
393 .immediate,
394 .memory,
395 .lea_frame,
396 .load_symbol,
397 .lea_symbol,
398 => assert(std.meta.eql(self.long, target.long)),
399 .load_frame,
400 .reserved_frame,
401 => switch (target.long) {
402 .none,
403 .load_frame,
404 .reserved_frame,
405 => {},
406 else => unreachable,
407 },
408 .dead,
409 .register,
410 .register_pair,
411 .register_offset,
412 .indirect,
413 .air_ref,
414 => unreachable,
415 }
416 }
417
418 fn materialize(
419 self: *InstTracking,
420 function: *Self,
421 inst: Air.Inst.Index,
422 target: InstTracking,
423 ) !void {
424 self.verifyMaterialize(target);
425 try self.materializeUnsafe(function, inst, target);
426 }
427
428 fn materializeUnsafe(
429 self: InstTracking,
430 function: *Self,
431 inst: Air.Inst.Index,
432 target: InstTracking,
433 ) !void {
434 const ty = function.typeOfIndex(inst);
435 if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame)
436 try function.genCopy(ty, target.long, self.short);
437 try function.genCopy(ty, target.short, self.short);
438 }
439
440 fn trackMaterialize(self: *InstTracking, inst: Air.Inst.Index, target: InstTracking) void {
441 self.verifyMaterialize(target);
442 // Don't clobber reserved frame indices
443 self.long = if (target.long == .none) switch (self.long) {
444 .load_frame => |addr| .{ .reserved_frame = addr.index },
445 .reserved_frame => self.long,
446 else => target.long,
447 } else target.long;
448 self.short = target.short;
449 tracking_log.debug("%{d} => {} (materialize)", .{ inst, self.* });
450 }
451
452 fn resurrect(self: *InstTracking, inst: Air.Inst.Index, scope_generation: u32) void {
453 switch (self.short) {
454 .dead => |die_generation| if (die_generation >= scope_generation) {
455 self.reuseFrame();
456 tracking_log.debug("%{d} => {} (resurrect)", .{ inst, self.* });
457 },
458 else => {},
459 }
460 }
461
462 fn die(self: *InstTracking, function: *Self, inst: Air.Inst.Index) !void {
463 if (self.short == .dead) return;
464 try function.freeValue(self.short);
465 self.short = .{ .dead = function.scope_generation };
466 tracking_log.debug("%{d} => {} (death)", .{ inst, self.* });
467 }
468
469 fn reuse(
470 self: *InstTracking,
471 function: *Self,
472 new_inst: ?Air.Inst.Index,
473 old_inst: Air.Inst.Index,
474 ) void {
475 self.short = .{ .dead = function.scope_generation };
476 if (new_inst) |inst|
477 tracking_log.debug("%{d} => {} (reuse %{d})", .{ inst, self.*, old_inst })
478 else
479 tracking_log.debug("tmp => {} (reuse %{d})", .{ self.*, old_inst });
480 }
481
482 fn liveOut(self: *InstTracking, function: *Self, inst: Air.Inst.Index) void {
483 for (self.getRegs()) |reg| {
484 if (function.register_manager.isRegFree(reg)) {
485 tracking_log.debug("%{d} => {} (live-out)", .{ inst, self.* });
486 continue;
487 }
488
489 const index = RegisterManager.indexOfRegIntoTracked(reg).?;
490 const tracked_inst = function.register_manager.registers[index];
491 const tracking = function.getResolvedInstValue(tracked_inst);
492
493 // Disable death.
494 var found_reg = false;
495 var remaining_reg: Register = .zero;
496 for (tracking.getRegs()) |tracked_reg| if (tracked_reg.id() == reg.id()) {
497 assert(!found_reg);
498 found_reg = true;
499 } else {
500 assert(remaining_reg == .zero);
501 remaining_reg = tracked_reg;
502 };
503 assert(found_reg);
504 tracking.short = switch (remaining_reg) {
505 .zero => .{ .dead = function.scope_generation },
506 else => .{ .register = remaining_reg },
507 };
508
509 // Perform side-effects of freeValue manually.
510 function.register_manager.freeReg(reg);
511
512 tracking_log.debug("%{d} => {} (live-out %{d})", .{ inst, self.*, tracked_inst });
513 }
514 }
515
516 pub fn format(
517 self: InstTracking,
518 comptime _: []const u8,
519 _: std.fmt.FormatOptions,
520 writer: anytype,
521 ) @TypeOf(writer).Error!void {
522 if (!std.meta.eql(self.long, self.short)) try writer.print("|{}| ", .{self.long});
523 try writer.print("{}", .{self.short});
524 }
525};
526
527const FrameAlloc = struct {
528 abi_size: u31,
529 spill_pad: u3,
530 abi_align: Alignment,
531 ref_count: u16,
532
533 fn init(alloc_abi: struct { size: u64, pad: u3 = 0, alignment: Alignment }) FrameAlloc {
534 return .{
535 .abi_size = @intCast(alloc_abi.size),
536 .spill_pad = alloc_abi.pad,
537 .abi_align = alloc_abi.alignment,
538 .ref_count = 0,
539 };
540 }
541 fn initType(ty: Type, zcu: *Module) FrameAlloc {
542 return init(.{
543 .size = ty.abiSize(zcu),
544 .alignment = ty.abiAlignment(zcu),
545 });
546 }
547 fn initSpill(ty: Type, zcu: *Module) FrameAlloc {
548 const abi_size = ty.abiSize(zcu);
549 const spill_size = if (abi_size < 8)
550 math.ceilPowerOfTwoAssert(u64, abi_size)
551 else
552 std.mem.alignForward(u64, abi_size, 8);
553 return init(.{
554 .size = spill_size,
555 .pad = @intCast(spill_size - abi_size),
556 .alignment = ty.abiAlignment(zcu).maxStrict(
557 Alignment.fromNonzeroByteUnits(@min(spill_size, 8)),
558 ),
559 });
560 }
561};
562
166563const StackAllocation = struct {
167 inst: Air.Inst.Index,
168 /// TODO do we need size? should be determined by inst.ty.abiSize()
564 inst: ?Air.Inst.Index,
565 /// TODO: make the size inferred from the bits of the inst
169566 size: u32,
170567};
171568
172569const BlockData = struct {
173 relocs: std.ArrayListUnmanaged(Reloc),
174 /// The first break instruction encounters `null` here and chooses a
175 /// machine code value for the block result, populating this field.
176 /// Following break instructions encounter that value and use it for
177 /// the location to store their block results.
178 mcv: MCValue,
570 relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .{},
571 state: State,
572
573 fn deinit(self: *BlockData, gpa: Allocator) void {
574 self.relocs.deinit(gpa);
575 self.* = undefined;
576 }
179577};
180578
181const Reloc = union(enum) {
182 /// The value is an offset into the `Function` `code` from the beginning.
183 /// To perform the reloc, write 32-bit signed little-endian integer
184 /// which is a relative jump, based on the address following the reloc.
185 rel32: usize,
186 /// A branch in the ARM instruction set
187 arm_branch: struct {
188 pos: usize,
189 cond: @import("../arm/bits.zig").Condition,
190 },
579const State = struct {
580 registers: RegisterManager.TrackedRegisters,
581 reg_tracking: [RegisterManager.RegisterBitSet.bit_length]InstTracking,
582 free_registers: RegisterManager.RegisterBitSet,
583 inst_tracking_len: u32,
584 scope_generation: u32,
191585};
192586
193const BigTomb = struct {
194 function: *Self,
195 inst: Air.Inst.Index,
196 lbt: Liveness.BigTomb,
587fn initRetroactiveState(self: *Self) State {
588 var state: State = undefined;
589 state.inst_tracking_len = @intCast(self.inst_tracking.count());
590 state.scope_generation = self.scope_generation;
591 return state;
592}
197593
198 fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) void {
199 const dies = bt.lbt.feed();
200 const op_index = op_ref.toIndex() orelse return;
201 if (!dies) return;
202 bt.function.processDeath(op_index);
594fn saveRetroactiveState(self: *Self, state: *State) !void {
595 const free_registers = self.register_manager.free_registers;
596 var it = free_registers.iterator(.{ .kind = .unset });
597 while (it.next()) |index| {
598 const tracked_inst = self.register_manager.registers[index];
599 state.registers[index] = tracked_inst;
600 state.reg_tracking[index] = self.inst_tracking.get(tracked_inst).?;
601 }
602 state.free_registers = free_registers;
603}
604
605fn saveState(self: *Self) !State {
606 var state = self.initRetroactiveState();
607 try self.saveRetroactiveState(&state);
608 return state;
609}
610
611fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, comptime opts: struct {
612 emit_instructions: bool,
613 update_tracking: bool,
614 resurrect: bool,
615 close_scope: bool,
616}) !void {
617 if (opts.close_scope) {
618 for (
619 self.inst_tracking.keys()[state.inst_tracking_len..],
620 self.inst_tracking.values()[state.inst_tracking_len..],
621 ) |inst, *tracking| try tracking.die(self, inst);
622 self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len);
203623 }
204624
205 fn finishAir(bt: *BigTomb, result: MCValue) void {
206 const is_used = !bt.function.liveness.isUnused(bt.inst);
207 if (is_used) {
208 log.debug("%{d} => {}", .{ bt.inst, result });
209 const branch = &bt.function.branch_stack.items[bt.function.branch_stack.items.len - 1];
210 branch.inst_table.putAssumeCapacityNoClobber(bt.inst, result);
625 if (opts.resurrect) for (
626 self.inst_tracking.keys()[0..state.inst_tracking_len],
627 self.inst_tracking.values()[0..state.inst_tracking_len],
628 ) |inst, *tracking| tracking.resurrect(inst, state.scope_generation);
629 for (deaths) |death| try self.processDeath(death);
630
631 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).Array.len]RegisterLock;
632 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
633 if (opts.update_tracking)
634 {} else std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
635
636 var reg_locks = if (opts.update_tracking) {} else try std.ArrayList(RegisterLock).initCapacity(
637 stack.get(),
638 @typeInfo(ExpectedContents).Array.len,
639 );
640 defer if (!opts.update_tracking) {
641 for (reg_locks.items) |lock| self.register_manager.unlockReg(lock);
642 reg_locks.deinit();
643 };
644
645 for (0..state.registers.len) |index| {
646 const current_maybe_inst = if (self.register_manager.free_registers.isSet(index))
647 null
648 else
649 self.register_manager.registers[index];
650 const target_maybe_inst = if (state.free_registers.isSet(index))
651 null
652 else
653 state.registers[index];
654 if (std.debug.runtime_safety) if (target_maybe_inst) |target_inst|
655 assert(self.inst_tracking.getIndex(target_inst).? < state.inst_tracking_len);
656 if (opts.emit_instructions) {
657 if (current_maybe_inst) |current_inst| {
658 try self.inst_tracking.getPtr(current_inst).?.spill(self, current_inst);
659 }
660 if (target_maybe_inst) |target_inst| {
661 const target_tracking = self.inst_tracking.getPtr(target_inst).?;
662 try target_tracking.materialize(self, target_inst, state.reg_tracking[index]);
663 }
211664 }
212 bt.function.finishAirBookkeeping();
665 if (opts.update_tracking) {
666 if (current_maybe_inst) |current_inst| {
667 try self.inst_tracking.getPtr(current_inst).?.trackSpill(self, current_inst);
668 }
669 {
670 const reg = RegisterManager.regAtTrackedIndex(@intCast(index));
671 self.register_manager.freeReg(reg);
672 self.register_manager.getRegAssumeFree(reg, target_maybe_inst);
673 }
674 if (target_maybe_inst) |target_inst| {
675 self.inst_tracking.getPtr(target_inst).?.trackMaterialize(
676 target_inst,
677 state.reg_tracking[index],
678 );
679 }
680 } else if (target_maybe_inst) |_|
681 try reg_locks.append(self.register_manager.lockRegIndexAssumeUnused(@intCast(index)));
213682 }
214};
683
684 if (opts.update_tracking and std.debug.runtime_safety) {
685 assert(self.register_manager.free_registers.eql(state.free_registers));
686 var used_reg_it = state.free_registers.iterator(.{ .kind = .unset });
687 while (used_reg_it.next()) |index|
688 assert(self.register_manager.registers[index] == state.registers[index]);
689 }
690}
215691
216692const Self = @This();
217693
694const CallView = enum(u1) {
695 callee,
696 caller,
697};
698
218699pub fn generate(
219 lf: *link.File,
700 bin_file: *link.File,
220701 src_loc: Module.SrcLoc,
221702 func_index: InternPool.Index,
222703 air: Air,
......@@ -224,14 +705,17 @@ pub fn generate(
224705 code: *std.ArrayList(u8),
225706 debug_output: DebugInfoOutput,
226707) CodeGenError!Result {
227 const gpa = lf.comp.gpa;
228 const zcu = lf.comp.module.?;
708 const comp = bin_file.comp;
709 const gpa = comp.gpa;
710 const zcu = comp.module.?;
711 const ip = &zcu.intern_pool;
229712 const func = zcu.funcInfo(func_index);
230713 const fn_owner_decl = zcu.declPtr(func.owner_decl);
231714 assert(fn_owner_decl.has_tv);
232715 const fn_type = fn_owner_decl.typeOf(zcu);
233716 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
234717 const target = &namespace.file_scope.mod.resolved_target.result;
718 const mod = namespace.file_scope.mod;
235719
236720 var branch_stack = std.ArrayList(Branch).init(gpa);
237721 defer {
......@@ -244,9 +728,10 @@ pub fn generate(
244728 var function = Self{
245729 .gpa = gpa,
246730 .air = air,
731 .mod = mod,
247732 .liveness = liveness,
248733 .target = target,
249 .bin_file = lf,
734 .bin_file = bin_file,
250735 .func_index = func_index,
251736 .code = code,
252737 .debug_output = debug_output,
......@@ -257,27 +742,69 @@ pub fn generate(
257742 .arg_index = 0,
258743 .branch_stack = &branch_stack,
259744 .src_loc = src_loc,
260 .stack_align = undefined,
261745 .end_di_line = func.rbrace_line,
262746 .end_di_column = func.rbrace_column,
747 .scope_generation = 0,
263748 };
264 defer function.stack.deinit(gpa);
265 defer function.blocks.deinit(gpa);
266 defer function.exitlude_jump_relocs.deinit(gpa);
749 defer {
750 function.frame_allocs.deinit(gpa);
751 function.free_frame_indices.deinit(gpa);
752 function.frame_locs.deinit(gpa);
753 var block_it = function.blocks.valueIterator();
754 while (block_it.next()) |block| block.deinit(gpa);
755 function.blocks.deinit(gpa);
756 function.inst_tracking.deinit(gpa);
757 function.const_tracking.deinit(gpa);
758 function.exitlude_jump_relocs.deinit(gpa);
759 function.mir_instructions.deinit(gpa);
760 function.mir_extra.deinit(gpa);
761 }
267762
268 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
763 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
764 function.frame_allocs.set(
765 @intFromEnum(FrameIndex.stack_frame),
766 FrameAlloc.init(.{
767 .size = 0,
768 .alignment = func.analysis(ip).stack_alignment.max(.@"1"),
769 }),
770 );
771 function.frame_allocs.set(
772 @intFromEnum(FrameIndex.call_frame),
773 FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }),
774 );
775
776 const fn_info = zcu.typeToFunc(fn_type).?;
777 var call_info = function.resolveCallingConventionValues(fn_info) catch |err| switch (err) {
269778 error.CodegenFail => return Result{ .fail = function.err_msg.? },
270779 error.OutOfRegisters => return Result{
271780 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
272781 },
273782 else => |e| return e,
274783 };
784
275785 defer call_info.deinit(&function);
276786
277787 function.args = call_info.args;
278788 function.ret_mcv = call_info.return_value;
279 function.stack_align = call_info.stack_align;
280 function.max_end_stack = call_info.stack_byte_count;
789 function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{
790 .size = Type.usize.abiSize(zcu),
791 .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align),
792 }));
793 function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{
794 .size = Type.usize.abiSize(zcu),
795 .alignment = Alignment.min(
796 call_info.stack_align,
797 Alignment.fromNonzeroByteUnits(function.target.stackAlignment()),
798 ),
799 }));
800 function.frame_allocs.set(@intFromEnum(FrameIndex.args_frame), FrameAlloc.init(.{
801 .size = call_info.stack_byte_count,
802 .alignment = call_info.stack_align,
803 }));
804 function.frame_allocs.set(@intFromEnum(FrameIndex.spill_frame), FrameAlloc.init(.{
805 .size = 0,
806 .alignment = Type.usize.abiAlignment(zcu),
807 }));
281808
282809 function.gen() catch |err| switch (err) {
283810 error.CodegenFail => return Result{ .fail = function.err_msg.? },
......@@ -290,15 +817,22 @@ pub fn generate(
290817 var mir = Mir{
291818 .instructions = function.mir_instructions.toOwnedSlice(),
292819 .extra = try function.mir_extra.toOwnedSlice(gpa),
820 .frame_locs = function.frame_locs.toOwnedSlice(),
293821 };
294822 defer mir.deinit(gpa);
295823
296824 var emit = Emit{
297 .mir = mir,
298 .bin_file = lf,
825 .lower = .{
826 .bin_file = bin_file,
827 .allocator = gpa,
828 .mir = mir,
829 .cc = fn_info.cc,
830 .src_loc = src_loc,
831 .output_mode = comp.config.output_mode,
832 .link_mode = comp.config.link_mode,
833 .pic = mod.pic,
834 },
299835 .debug_output = debug_output,
300 .target = target,
301 .src_loc = src_loc,
302836 .code = code,
303837 .prev_di_pc = 0,
304838 .prev_di_line = func.lbrace_line,
......@@ -307,7 +841,20 @@ pub fn generate(
307841 defer emit.deinit();
308842
309843 emit.emitMir() catch |err| switch (err) {
310 error.EmitFail => return Result{ .fail = emit.err_msg.? },
844 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
845 error.InvalidInstruction => |e| {
846 const msg = switch (e) {
847 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
848 };
849 return Result{
850 .fail = try ErrorMsg.create(
851 gpa,
852 src_loc,
853 "{s} This is a bug in the Zig compiler.",
854 .{msg},
855 ),
856 };
857 },
311858 else => |e| return e,
312859 };
313860
......@@ -328,6 +875,30 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
328875 return result_index;
329876}
330877
878fn addNop(self: *Self) error{OutOfMemory}!Mir.Inst.Index {
879 return self.addInst(.{
880 .tag = .nop,
881 .ops = .none,
882 .data = undefined,
883 });
884}
885
886fn addPseudoNone(self: *Self, ops: Mir.Inst.Ops) !void {
887 _ = try self.addInst(.{
888 .tag = .pseudo,
889 .ops = ops,
890 .data = undefined,
891 });
892}
893
894fn addPseudo(self: *Self, ops: Mir.Inst.Ops) !Mir.Inst.Index {
895 return self.addInst(.{
896 .tag = .pseudo,
897 .ops = ops,
898 .data = undefined,
899 });
900}
901
331902pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 {
332903 const fields = std.meta.fields(@TypeOf(extra));
333904 try self.mir_extra.ensureUnusedCapacity(self.gpa, fields.len);
......@@ -349,122 +920,131 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
349920
350921fn gen(self: *Self) !void {
351922 const mod = self.bin_file.comp.module.?;
352 const cc = self.fn_type.fnCallingConvention(mod);
353 if (cc != .Naked) {
354 // TODO Finish function prologue and epilogue for riscv64.
923 const fn_info = mod.typeToFunc(self.fn_type).?;
355924
356 // TODO Backpatch stack offset
357 // addi sp, sp, -16
358 _ = try self.addInst(.{
925 if (fn_info.cc != .Naked) {
926 try self.addPseudoNone(.pseudo_dbg_prologue_end);
927
928 const backpatch_stack_alloc = try self.addPseudo(.pseudo_dead);
929 const backpatch_ra_spill = try self.addPseudo(.pseudo_dead);
930 const backpatch_fp_spill = try self.addPseudo(.pseudo_dead);
931 const backpatch_fp_add = try self.addPseudo(.pseudo_dead);
932 const backpatch_spill_callee_preserved_regs = try self.addPseudo(.pseudo_dead);
933
934 try self.genBody(self.air.getMainBody());
935
936 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
937 self.mir_instructions.items(.data)[jmp_reloc].inst =
938 @intCast(self.mir_instructions.len);
939 }
940
941 try self.addPseudoNone(.pseudo_dbg_epilogue_begin);
942
943 const backpatch_restore_callee_preserved_regs = try self.addPseudo(.pseudo_dead);
944 const backpatch_ra_restore = try self.addPseudo(.pseudo_dead);
945 const backpatch_fp_restore = try self.addPseudo(.pseudo_dead);
946 const backpatch_stack_alloc_restore = try self.addPseudo(.pseudo_dead);
947 try self.addPseudoNone(.pseudo_ret);
948
949 const frame_layout = try self.computeFrameLayout();
950 const need_save_reg = frame_layout.save_reg_list.count() > 0;
951
952 self.mir_instructions.set(backpatch_stack_alloc, .{
359953 .tag = .addi,
954 .ops = .rri,
360955 .data = .{ .i_type = .{
361956 .rd = .sp,
362957 .rs1 = .sp,
363 .imm12 = -16,
958 .imm12 = Immediate.s(-@as(i32, @intCast(frame_layout.stack_adjust))),
364959 } },
365960 });
366
367 // sd ra, 8(sp)
368 _ = try self.addInst(.{
369 .tag = .sd,
370 .data = .{ .i_type = .{
371 .rd = .ra,
372 .rs1 = .sp,
373 .imm12 = 8,
961 self.mir_instructions.set(backpatch_ra_spill, .{
962 .tag = .pseudo,
963 .ops = .pseudo_store_rm,
964 .data = .{ .rm = .{
965 .r = .ra,
966 .m = .{
967 .base = .{ .frame = .ret_addr },
968 .mod = .{ .rm = .{ .size = .dword } },
969 },
374970 } },
375971 });
376
377 // sd s0, 0(sp)
378 _ = try self.addInst(.{
379 .tag = .sd,
380 .data = .{ .i_type = .{
381 .rd = .s0,
382 .rs1 = .sp,
383 .imm12 = 0,
972 self.mir_instructions.set(backpatch_ra_restore, .{
973 .tag = .pseudo,
974 .ops = .pseudo_load_rm,
975 .data = .{ .rm = .{
976 .r = .ra,
977 .m = .{
978 .base = .{ .frame = .ret_addr },
979 .mod = .{ .rm = .{ .size = .dword } },
980 },
384981 } },
385982 });
386
387 _ = try self.addInst(.{
388 .tag = .dbg_prologue_end,
389 .data = .{ .nop = {} },
390 });
391
392 try self.genBody(self.air.getMainBody());
393
394 _ = try self.addInst(.{
395 .tag = .dbg_epilogue_begin,
396 .data = .{ .nop = {} },
983 self.mir_instructions.set(backpatch_fp_spill, .{
984 .tag = .pseudo,
985 .ops = .pseudo_store_rm,
986 .data = .{ .rm = .{
987 .r = .s0,
988 .m = .{
989 .base = .{ .frame = .base_ptr },
990 .mod = .{ .rm = .{ .size = .dword } },
991 },
992 } },
397993 });
398
399 // exitlude jumps
400 if (self.exitlude_jump_relocs.items.len > 0 and
401 self.exitlude_jump_relocs.items[self.exitlude_jump_relocs.items.len - 1] == self.mir_instructions.len - 2)
402 {
403 // If the last Mir instruction (apart from the
404 // dbg_epilogue_begin) is the last exitlude jump
405 // relocation (which would just jump one instruction
406 // further), it can be safely removed
407 self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.pop());
408 }
409
410 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
411 _ = jmp_reloc;
412 return self.fail("TODO add branches in RISCV64", .{});
413 }
414
415 // ld ra, 8(sp)
416 _ = try self.addInst(.{
417 .tag = .ld,
418 .data = .{ .i_type = .{
419 .rd = .ra,
420 .rs1 = .sp,
421 .imm12 = 8,
994 self.mir_instructions.set(backpatch_fp_restore, .{
995 .tag = .pseudo,
996 .ops = .pseudo_load_rm,
997 .data = .{ .rm = .{
998 .r = .s0,
999 .m = .{
1000 .base = .{ .frame = .base_ptr },
1001 .mod = .{ .rm = .{ .size = .dword } },
1002 },
4221003 } },
4231004 });
424
425 // ld s0, 0(sp)
426 _ = try self.addInst(.{
427 .tag = .ld,
1005 self.mir_instructions.set(backpatch_fp_add, .{
1006 .tag = .addi,
1007 .ops = .rri,
4281008 .data = .{ .i_type = .{
4291009 .rd = .s0,
4301010 .rs1 = .sp,
431 .imm12 = 0,
1011 .imm12 = Immediate.s(@intCast(frame_layout.stack_adjust)),
4321012 } },
4331013 });
434
435 // addi sp, sp, 16
436 _ = try self.addInst(.{
1014 self.mir_instructions.set(backpatch_stack_alloc_restore, .{
4371015 .tag = .addi,
1016 .ops = .rri,
4381017 .data = .{ .i_type = .{
4391018 .rd = .sp,
4401019 .rs1 = .sp,
441 .imm12 = 16,
1020 .imm12 = Immediate.s(@intCast(frame_layout.stack_adjust)),
4421021 } },
4431022 });
4441023
445 // ret
446 _ = try self.addInst(.{
447 .tag = .ret,
448 .data = .{ .nop = {} },
449 });
450 } else {
451 _ = try self.addInst(.{
452 .tag = .dbg_prologue_end,
453 .data = .{ .nop = {} },
454 });
1024 if (need_save_reg) {
1025 self.mir_instructions.set(backpatch_spill_callee_preserved_regs, .{
1026 .tag = .pseudo,
1027 .ops = .pseudo_spill_regs,
1028 .data = .{ .reg_list = frame_layout.save_reg_list },
1029 });
4551030
1031 self.mir_instructions.set(backpatch_restore_callee_preserved_regs, .{
1032 .tag = .pseudo,
1033 .ops = .pseudo_restore_regs,
1034 .data = .{ .reg_list = frame_layout.save_reg_list },
1035 });
1036 }
1037 } else {
1038 try self.addPseudoNone(.pseudo_dbg_prologue_end);
4561039 try self.genBody(self.air.getMainBody());
457
458 _ = try self.addInst(.{
459 .tag = .dbg_epilogue_begin,
460 .data = .{ .nop = {} },
461 });
1040 try self.addPseudoNone(.pseudo_dbg_epilogue_begin);
4621041 }
4631042
4641043 // Drop them off at the rbrace.
4651044 _ = try self.addInst(.{
466 .tag = .dbg_line,
467 .data = .{ .dbg_line_column = .{
1045 .tag = .pseudo,
1046 .ops = .pseudo_dbg_line_column,
1047 .data = .{ .pseudo_dbg_line_column = .{
4681048 .line = self.end_di_line,
4691049 .column = self.end_di_column,
4701050 } },
......@@ -472,18 +1052,15 @@ fn gen(self: *Self) !void {
4721052}
4731053
4741054fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
475 const mod = self.bin_file.comp.module.?;
476 const ip = &mod.intern_pool;
1055 const zcu = self.bin_file.comp.module.?;
1056 const ip = &zcu.intern_pool;
4771057 const air_tags = self.air.instructions.items(.tag);
4781058
4791059 for (body) |inst| {
480 // TODO: remove now-redundant isUnused calls from AIR handler functions
481 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
482 continue;
1060 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
4831061
4841062 const old_air_bookkeeping = self.air_bookkeeping;
485 try self.ensureProcessDeathCapacity(Liveness.bpi);
486
1063 try self.inst_tracking.ensureUnusedCapacity(self.gpa, 1);
4871064 switch (air_tags[@intFromEnum(inst)]) {
4881065 // zig fmt: off
4891066 .ptr_add => try self.airPtrArithmetic(inst, .ptr_add),
......@@ -508,8 +1085,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
5081085 .mod => try self.airMod(inst),
5091086 .shl, .shl_exact => try self.airShl(inst),
5101087 .shl_sat => try self.airShlSat(inst),
511 .min => try self.airMin(inst),
512 .max => try self.airMax(inst),
1088 .min => try self.airMinMax(inst, .min),
1089 .max => try self.airMinMax(inst, .max),
5131090 .slice => try self.airSlice(inst),
5141091
5151092 .sqrt,
......@@ -535,12 +1112,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
5351112
5361113 .div_float, .div_trunc, .div_floor, .div_exact => try self.airDiv(inst),
5371114
538 .cmp_lt => try self.airCmp(inst, .lt),
539 .cmp_lte => try self.airCmp(inst, .lte),
540 .cmp_eq => try self.airCmp(inst, .eq),
541 .cmp_gte => try self.airCmp(inst, .gte),
542 .cmp_gt => try self.airCmp(inst, .gt),
543 .cmp_neq => try self.airCmp(inst, .neq),
1115 .cmp_lt => try self.airCmp(inst),
1116 .cmp_lte => try self.airCmp(inst),
1117 .cmp_eq => try self.airCmp(inst),
1118 .cmp_gte => try self.airCmp(inst),
1119 .cmp_gt => try self.airCmp(inst),
1120 .cmp_neq => try self.airCmp(inst),
5441121
5451122 .cmp_vector => try self.airCmpVector(inst),
5461123 .cmp_lt_errors_len => try self.airCmpLtErrorsLen(inst),
......@@ -565,11 +1142,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
5651142 .frame_addr => try self.airFrameAddress(inst),
5661143 .fence => try self.airFence(),
5671144 .cond_br => try self.airCondBr(inst),
1145 .dbg_stmt => try self.airDbgStmt(inst),
5681146 .fptrunc => try self.airFptrunc(inst),
5691147 .fpext => try self.airFpext(inst),
5701148 .intcast => try self.airIntCast(inst),
5711149 .trunc => try self.airTrunc(inst),
572 .int_from_bool => try self.airIntFromBool(inst),
1150 .int_from_bool => try self.airIntFromBool(inst),
5731151 .is_non_null => try self.airIsNonNull(inst),
5741152 .is_non_null_ptr => try self.airIsNonNullPtr(inst),
5751153 .is_null => try self.airIsNull(inst),
......@@ -581,17 +1159,17 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
5811159 .load => try self.airLoad(inst),
5821160 .loop => try self.airLoop(inst),
5831161 .not => try self.airNot(inst),
584 .int_from_ptr => try self.airIntFromPtr(inst),
585 .ret => try self.airRet(inst),
586 .ret_safe => try self.airRet(inst), // TODO
1162 .int_from_ptr => try self.airIntFromPtr(inst),
1163 .ret => try self.airRet(inst, false),
1164 .ret_safe => try self.airRet(inst, true),
5871165 .ret_load => try self.airRetLoad(inst),
5881166 .store => try self.airStore(inst, false),
5891167 .store_safe => try self.airStore(inst, true),
5901168 .struct_field_ptr=> try self.airStructFieldPtr(inst),
5911169 .struct_field_val=> try self.airStructFieldVal(inst),
5921170 .array_to_slice => try self.airArrayToSlice(inst),
593 .float_from_int => try self.airFloatFromInt(inst),
594 .int_from_float => try self.airIntFromFloat(inst),
1171 .float_from_int => try self.airFloatFromInt(inst),
1172 .int_from_float => try self.airIntFromFloat(inst),
5951173 .cmpxchg_strong => try self.airCmpxchg(inst),
5961174 .cmpxchg_weak => try self.airCmpxchg(inst),
5971175 .atomic_rmw => try self.airAtomicRmw(inst),
......@@ -617,17 +1195,17 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
6171195 .union_init => try self.airUnionInit(inst),
6181196 .prefetch => try self.airPrefetch(inst),
6191197 .mul_add => try self.airMulAdd(inst),
620 .addrspace_cast => @panic("TODO"),
1198 .addrspace_cast => return self.fail("TODO: addrspace_cast", .{}),
6211199
622 .@"try" => @panic("TODO"),
623 .try_ptr => @panic("TODO"),
1200 .@"try" => try self.airTry(inst),
1201 .try_ptr => return self.fail("TODO: try_ptr", .{}),
6241202
625 .dbg_stmt => try self.airDbgStmt(inst),
626 .dbg_inline_block => try self.airDbgInlineBlock(inst),
6271203 .dbg_var_ptr,
6281204 .dbg_var_val,
6291205 => try self.airDbgVar(inst),
6301206
1207 .dbg_inline_block => try self.airDbgInlineBlock(inst),
1208
6311209 .call => try self.airCall(inst, .auto),
6321210 .call_always_tail => try self.airCall(inst, .always_tail),
6331211 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -715,28 +1293,60 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
7151293 .work_group_id => unreachable,
7161294 // zig fmt: on
7171295 }
1296
1297 assert(!self.register_manager.lockedRegsExist());
1298
7181299 if (std.debug.runtime_safety) {
7191300 if (self.air_bookkeeping < old_air_bookkeeping + 1) {
7201301 std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[@intFromEnum(inst)] });
7211302 }
1303
1304 { // check consistency of tracked registers
1305 var it = self.register_manager.free_registers.iterator(.{ .kind = .unset });
1306 while (it.next()) |index| {
1307 const tracked_inst = self.register_manager.registers[index];
1308 const tracking = self.getResolvedInstValue(tracked_inst);
1309 for (tracking.getRegs()) |reg| {
1310 if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;
1311 } else return self.fail(
1312 \\%{} takes up these regs: {any}, however those regs don't use it
1313 , .{ index, tracking.getRegs() });
1314 }
1315 }
7221316 }
7231317 }
7241318}
7251319
726/// Asserts there is already capacity to insert into top branch inst_table.
727fn processDeath(self: *Self, inst: Air.Inst.Index) void {
728 // When editing this function, note that the logic must synchronize with `reuseOperand`.
729 const prev_value = self.getResolvedInstValue(inst);
730 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
731 branch.inst_table.putAssumeCapacity(inst, .dead);
732 switch (prev_value) {
733 .register => |reg| {
734 self.register_manager.freeReg(reg);
735 },
1320fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) !void {
1321 for (value.getRegs()) |reg| try self.register_manager.getReg(reg, inst);
1322}
1323
1324fn getValueIfFree(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void {
1325 for (value.getRegs()) |reg| if (self.register_manager.isRegFree(reg))
1326 self.register_manager.getRegAssumeFree(reg, inst);
1327}
1328
1329fn freeValue(self: *Self, value: MCValue) !void {
1330 switch (value) {
1331 .register => |reg| self.register_manager.freeReg(reg),
1332 .register_pair => |regs| for (regs) |reg| self.register_manager.freeReg(reg),
1333 .register_offset => |reg_off| self.register_manager.freeReg(reg_off.reg),
7361334 else => {}, // TODO process stack allocation death
7371335 }
7381336}
7391337
1338fn feed(self: *Self, bt: *Liveness.BigTomb, operand: Air.Inst.Ref) !void {
1339 if (bt.feed()) if (operand.toIndex()) |inst| {
1340 log.debug("feed inst: %{}", .{inst});
1341 try self.processDeath(inst);
1342 };
1343}
1344
1345/// Asserts there is already capacity to insert into top branch inst_table.
1346fn processDeath(self: *Self, inst: Air.Inst.Index) !void {
1347 try self.inst_tracking.getPtr(inst).?.die(self, inst);
1348}
1349
7401350/// Called when there are no operands, and the instruction is always unreferenced.
7411351fn finishAirBookkeeping(self: *Self) void {
7421352 if (std.debug.runtime_safety) {
......@@ -744,36 +1354,143 @@ fn finishAirBookkeeping(self: *Self) void {
7441354 }
7451355}
7461356
747fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Liveness.bpi - 1]Air.Inst.Ref) void {
1357fn finishAirResult(self: *Self, inst: Air.Inst.Index, result: MCValue) void {
1358 if (self.liveness.isUnused(inst)) switch (result) {
1359 .none, .dead, .unreach => {},
1360 else => unreachable, // Why didn't the result die?
1361 } else {
1362 tracking_log.debug("%{d} => {} (birth)", .{ inst, result });
1363 self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(result));
1364 // In some cases, an operand may be reused as the result.
1365 // If that operand died and was a register, it was freed by
1366 // processDeath, so we have to "re-allocate" the register.
1367 self.getValueIfFree(result, inst);
1368 }
1369 self.finishAirBookkeeping();
1370}
1371
1372fn finishAir(
1373 self: *Self,
1374 inst: Air.Inst.Index,
1375 result: MCValue,
1376 operands: [Liveness.bpi - 1]Air.Inst.Ref,
1377) !void {
7481378 var tomb_bits = self.liveness.getTombBits(inst);
7491379 for (operands) |op| {
7501380 const dies = @as(u1, @truncate(tomb_bits)) != 0;
7511381 tomb_bits >>= 1;
7521382 if (!dies) continue;
753 const op_index = op.toIndex() orelse continue;
754 self.processDeath(op_index);
1383 try self.processDeath(op.toIndexAllowNone() orelse continue);
7551384 }
756 const is_used = @as(u1, @truncate(tomb_bits)) == 0;
757 if (is_used) {
758 log.debug("%{d} => {}", .{ inst, result });
759 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
760 branch.inst_table.putAssumeCapacityNoClobber(inst, result);
1385 self.finishAirResult(inst, result);
1386}
7611387
762 switch (result) {
763 .register => |reg| {
764 // In some cases (such as bitcast), an operand
765 // may be the same MCValue as the result. If
766 // that operand died and was a register, it
767 // was freed by processDeath. We have to
768 // "re-allocate" the register.
769 if (self.register_manager.isRegFree(reg)) {
770 self.register_manager.getRegAssumeFree(reg, inst);
771 }
772 },
773 else => {},
1388const FrameLayout = struct {
1389 stack_adjust: u32,
1390 save_reg_list: Mir.RegisterList,
1391};
1392
1393fn setFrameLoc(
1394 self: *Self,
1395 frame_index: FrameIndex,
1396 base: Register,
1397 offset: *i32,
1398 comptime aligned: bool,
1399) void {
1400 const frame_i = @intFromEnum(frame_index);
1401 if (aligned) {
1402 const alignment: InternPool.Alignment = self.frame_allocs.items(.abi_align)[frame_i];
1403 offset.* = if (math.sign(offset.*) < 0)
1404 -1 * @as(i32, @intCast(alignment.backward(@intCast(@abs(offset.*)))))
1405 else
1406 @intCast(alignment.forward(@intCast(@abs(offset.*))));
1407 }
1408 self.frame_locs.set(frame_i, .{ .base = base, .disp = offset.* });
1409 offset.* += self.frame_allocs.items(.abi_size)[frame_i];
1410}
1411
1412fn computeFrameLayout(self: *Self) !FrameLayout {
1413 const frame_allocs_len = self.frame_allocs.len;
1414 try self.frame_locs.resize(self.gpa, frame_allocs_len);
1415 const stack_frame_order = try self.gpa.alloc(FrameIndex, frame_allocs_len - FrameIndex.named_count);
1416 defer self.gpa.free(stack_frame_order);
1417
1418 const frame_size = self.frame_allocs.items(.abi_size);
1419 const frame_align = self.frame_allocs.items(.abi_align);
1420
1421 for (stack_frame_order, FrameIndex.named_count..) |*frame_order, frame_index|
1422 frame_order.* = @enumFromInt(frame_index);
1423
1424 {
1425 const SortContext = struct {
1426 frame_align: @TypeOf(frame_align),
1427 pub fn lessThan(context: @This(), lhs: FrameIndex, rhs: FrameIndex) bool {
1428 return context.frame_align[@intFromEnum(lhs)].compare(.gt, context.frame_align[@intFromEnum(rhs)]);
1429 }
1430 };
1431 const sort_context = SortContext{ .frame_align = frame_align };
1432 mem.sort(FrameIndex, stack_frame_order, sort_context, SortContext.lessThan);
1433 }
1434
1435 var save_reg_list = Mir.RegisterList{};
1436 for (callee_preserved_regs) |reg| {
1437 if (self.register_manager.isRegAllocated(reg)) {
1438 save_reg_list.push(&callee_preserved_regs, reg);
7741439 }
7751440 }
776 self.finishAirBookkeeping();
1441
1442 const total_alloc_size: i32 = blk: {
1443 var i: i32 = 0;
1444 for (stack_frame_order) |frame_index| {
1445 i += frame_size[@intFromEnum(frame_index)];
1446 }
1447 break :blk i;
1448 };
1449 const saved_reg_size = save_reg_list.size();
1450
1451 frame_size[@intFromEnum(FrameIndex.spill_frame)] = @intCast(saved_reg_size);
1452
1453 // The total frame size is calculated by the amount of s registers you need to save * 8, as each
1454 // register is 8 bytes, the total allocation sizes, and 16 more register for the spilled ra and s0
1455 // register. Finally we align the frame size to the align of the base pointer.
1456 const args_frame_size = frame_size[@intFromEnum(FrameIndex.args_frame)];
1457 const spill_frame_size = frame_size[@intFromEnum(FrameIndex.spill_frame)];
1458 const call_frame_size = frame_size[@intFromEnum(FrameIndex.call_frame)];
1459
1460 // TODO: this 64 should be a 16, but we were clobbering the top and bottom of the frame.
1461 // maybe everything can go from the bottom?
1462 const acc_frame_size: i32 = std.mem.alignForward(
1463 i32,
1464 total_alloc_size + 64 + args_frame_size + spill_frame_size + call_frame_size,
1465 @intCast(frame_align[@intFromEnum(FrameIndex.base_ptr)].toByteUnits().?),
1466 );
1467 log.debug("frame size: {}", .{acc_frame_size});
1468
1469 // store the ra at total_size - 8, so it's the very first thing in the stack
1470 // relative to the fp
1471 self.frame_locs.set(
1472 @intFromEnum(FrameIndex.ret_addr),
1473 .{ .base = .sp, .disp = acc_frame_size - 8 },
1474 );
1475 self.frame_locs.set(
1476 @intFromEnum(FrameIndex.base_ptr),
1477 .{ .base = .sp, .disp = acc_frame_size - 16 },
1478 );
1479
1480 // now we grow the stack frame from the bottom of total frame in order to
1481 // not need to know the size of the first allocation. Stack offsets point at the "bottom"
1482 // of variables.
1483 var s0_offset: i32 = -acc_frame_size;
1484 self.setFrameLoc(.stack_frame, .s0, &s0_offset, true);
1485 for (stack_frame_order) |frame_index| self.setFrameLoc(frame_index, .s0, &s0_offset, true);
1486 self.setFrameLoc(.args_frame, .s0, &s0_offset, true);
1487 self.setFrameLoc(.call_frame, .s0, &s0_offset, true);
1488 self.setFrameLoc(.spill_frame, .s0, &s0_offset, true);
1489
1490 return .{
1491 .stack_adjust = @intCast(acc_frame_size),
1492 .save_reg_list = save_reg_list,
1493 };
7771494}
7781495
7791496fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
......@@ -781,40 +1498,94 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
7811498 try table.ensureUnusedCapacity(self.gpa, additional_count);
7821499}
7831500
784fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignment) !u32 {
785 self.stack_align = self.stack_align.max(abi_align);
786 // TODO find a free slot instead of always appending
787 const offset: u32 = @intCast(abi_align.forward(self.next_stack_offset));
788 self.next_stack_offset = offset + abi_size;
789 if (self.next_stack_offset > self.max_end_stack)
790 self.max_end_stack = self.next_stack_offset;
791 try self.stack.putNoClobber(self.gpa, offset, .{
792 .inst = inst,
793 .size = abi_size,
794 });
795 return offset;
1501fn memSize(self: *Self, ty: Type) Memory.Size {
1502 const mod = self.bin_file.comp.module.?;
1503 return switch (ty.zigTypeTag(mod)) {
1504 .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),
1505 else => Memory.Size.fromByteSize(ty.abiSize(mod)),
1506 };
7961507}
7971508
798/// Use a pointer instruction as the basis for allocating stack memory.
799fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
800 const mod = self.bin_file.comp.module.?;
801 const elem_ty = self.typeOfIndex(inst).childType(mod);
802 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
803 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1509fn splitType(self: *Self, ty: Type) ![2]Type {
1510 const zcu = self.bin_file.comp.module.?;
1511 const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none);
1512 var parts: [2]Type = undefined;
1513 if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| {
1514 part.* = switch (class) {
1515 .integer => switch (part_i) {
1516 0 => Type.u64,
1517 1 => part: {
1518 const elem_size = ty.abiAlignment(zcu).minStrict(.@"8").toByteUnits().?;
1519 const elem_ty = try zcu.intType(.unsigned, @intCast(elem_size * 8));
1520 break :part switch (@divExact(ty.abiSize(zcu) - 8, elem_size)) {
1521 1 => elem_ty,
1522 else => |len| try zcu.arrayType(.{ .len = len, .child = elem_ty.toIntern() }),
1523 };
1524 },
1525 else => unreachable,
1526 },
1527 else => return self.fail("TODO: splitType class {}", .{class}),
1528 };
1529 } else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts;
1530 return self.fail("TODO implement splitType for {}", .{ty.fmt(zcu)});
1531}
1532
1533fn symbolIndex(self: *Self) !u32 {
1534 const zcu = self.bin_file.comp.module.?;
1535 const decl_index = zcu.funcOwnerDeclIndex(self.func_index);
1536 return switch (self.bin_file.tag) {
1537 .elf => blk: {
1538 const elf_file = self.bin_file.cast(link.File.Elf).?;
1539 const atom_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
1540 break :blk atom_index;
1541 },
1542 else => return self.fail("TODO genSetReg load_symbol for {s}", .{@tagName(self.bin_file.tag)}),
8041543 };
805 // TODO swap this for inst.ty.ptrAlign
806 const abi_align = elem_ty.abiAlignment(mod);
807 return self.allocMem(inst, abi_size, abi_align);
1544}
1545
1546fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
1547 const frame_allocs_slice = self.frame_allocs.slice();
1548 const frame_size = frame_allocs_slice.items(.abi_size);
1549 const frame_align = frame_allocs_slice.items(.abi_align);
1550
1551 const stack_frame_align = &frame_align[@intFromEnum(FrameIndex.stack_frame)];
1552 stack_frame_align.* = stack_frame_align.max(alloc.abi_align);
1553
1554 for (self.free_frame_indices.keys(), 0..) |frame_index, free_i| {
1555 const abi_size = frame_size[@intFromEnum(frame_index)];
1556 if (abi_size != alloc.abi_size) continue;
1557 const abi_align = &frame_align[@intFromEnum(frame_index)];
1558 abi_align.* = abi_align.max(alloc.abi_align);
1559
1560 _ = self.free_frame_indices.swapRemoveAt(free_i);
1561 return frame_index;
1562 }
1563 const frame_index: FrameIndex = @enumFromInt(self.frame_allocs.len);
1564 try self.frame_allocs.append(self.gpa, alloc);
1565 log.debug("allocated frame {}", .{frame_index});
1566 return frame_index;
1567}
1568
1569/// Use a pointer instruction as the basis for allocating stack memory.
1570fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
1571 const zcu = self.bin_file.comp.module.?;
1572 const ptr_ty = self.typeOfIndex(inst);
1573 const val_ty = ptr_ty.childType(zcu);
1574 return self.allocFrameIndex(FrameAlloc.init(.{
1575 .size = math.cast(u32, val_ty.abiSize(zcu)) orelse {
1576 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(zcu)});
1577 },
1578 .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"),
1579 }));
8081580}
8091581
8101582fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
811 const mod = self.bin_file.comp.module.?;
1583 const zcu = self.bin_file.comp.module.?;
8121584 const elem_ty = self.typeOfIndex(inst);
813 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
814 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
1585
1586 const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse {
1587 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(zcu)});
8151588 };
816 const abi_align = elem_ty.abiAlignment(mod);
817 self.stack_align = self.stack_align.max(abi_align);
8181589
8191590 if (reg_ok) {
8201591 // Make sure the type can fit in a register before we try to allocate one.
......@@ -822,29 +1593,67 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
8221593 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
8231594 if (abi_size <= ptr_bytes) {
8241595 if (self.register_manager.tryAllocReg(inst, gp)) |reg| {
825 return MCValue{ .register = reg };
1596 return .{ .register = reg };
8261597 }
8271598 }
8281599 }
829 const stack_offset = try self.allocMem(inst, abi_size, abi_align);
830 return MCValue{ .stack_offset = stack_offset };
1600
1601 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(elem_ty, zcu));
1602 return .{ .load_frame = .{ .index = frame_index } };
1603}
1604
1605/// Allocates a register from the general purpose set and returns the Register and the Lock.
1606///
1607/// Up to the user to unlock the register later.
1608fn allocReg(self: *Self) !struct { Register, RegisterLock } {
1609 const reg = try self.register_manager.allocReg(null, gp);
1610 const lock = self.register_manager.lockRegAssumeUnused(reg);
1611 return .{ reg, lock };
1612}
1613
1614fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Register {
1615 const reg: Register = blk: {
1616 switch (index) {
1617 .immediate => |imm| {
1618 // Optimisation: if index MCValue is an immediate, we can multiply in `comptime`
1619 // and set the register directly to the scaled offset as an immediate.
1620 const reg = try self.register_manager.allocReg(null, gp);
1621 try self.genSetReg(index_ty, reg, .{ .immediate = imm * elem_size });
1622 break :blk reg;
1623 },
1624 else => {
1625 const reg = try self.copyToTmpRegister(index_ty, index);
1626 const lock = self.register_manager.lockRegAssumeUnused(reg);
1627 defer self.register_manager.unlockReg(lock);
1628
1629 const result = try self.binOp(
1630 .mul,
1631 .{ .register = reg },
1632 index_ty,
1633 .{ .immediate = elem_size },
1634 index_ty,
1635 );
1636 break :blk result.register;
1637 },
1638 }
1639 };
1640 return reg;
8311641}
8321642
8331643pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
834 const stack_mcv = try self.allocRegOrMem(inst, false);
835 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });
836 const reg_mcv = self.getResolvedInstValue(inst);
837 assert(reg == reg_mcv.register);
838 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
839 try branch.inst_table.put(self.gpa, inst, stack_mcv);
840 try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
1644 const tracking = self.inst_tracking.getPtr(inst) orelse return;
1645 for (tracking.getRegs()) |tracked_reg| {
1646 if (tracked_reg.id() == reg.id()) break;
1647 } else unreachable; // spilled reg not tracked with spilled instruciton
1648 try tracking.spill(self, inst);
1649 try tracking.trackSpill(self, inst);
8411650}
8421651
8431652/// Copies a value to a register without tracking the register. The register is not considered
8441653/// allocated. A second call to `copyToTmpRegister` may return the same register.
8451654/// This can have a side effect of spilling instructions to the stack to free up a register.
8461655fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
847 const reg = try self.register_manager.allocReg(null, gp);
1656 const reg = try self.register_manager.allocReg(null, tp);
8481657 try self.genSetReg(ty, reg, mcv);
8491658 return reg;
8501659}
......@@ -859,51 +1668,84 @@ fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCVa
8591668}
8601669
8611670fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
862 const stack_offset = try self.allocMemPtr(inst);
863 return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none });
1671 const result = MCValue{ .lea_frame = .{ .index = try self.allocMemPtr(inst) } };
1672 return self.finishAir(inst, result, .{ .none, .none, .none });
8641673}
8651674
8661675fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
867 const stack_offset = try self.allocMemPtr(inst);
868 return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none });
1676 const result: MCValue = switch (self.ret_mcv.long) {
1677 .none => .{ .lea_frame = .{ .index = try self.allocMemPtr(inst) } },
1678 .load_frame => .{ .register_offset = .{
1679 .reg = (try self.copyToNewRegister(
1680 inst,
1681 self.ret_mcv.long,
1682 )).register,
1683 .off = self.ret_mcv.short.indirect.off,
1684 } },
1685 else => |t| return self.fail("TODO: airRetPtr {s}", .{@tagName(t)}),
1686 };
1687 return self.finishAir(inst, result, .{ .none, .none, .none });
8691688}
8701689
8711690fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
8721691 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
873 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFptrunc for {}", .{self.target.cpu.arch});
1692 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airFptrunc for {}", .{self.target.cpu.arch});
8741693 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
8751694}
8761695
8771696fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
8781697 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
879 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFpext for {}", .{self.target.cpu.arch});
1698 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airFpext for {}", .{self.target.cpu.arch});
8801699 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
8811700}
8821701
8831702fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1703 const zcu = self.bin_file.comp.module.?;
8841704 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
885 if (self.liveness.isUnused(inst))
886 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
1705 const src_ty = self.typeOf(ty_op.operand);
1706 const dst_ty = self.typeOfIndex(inst);
8871707
888 const mod = self.bin_file.comp.module.?;
889 const operand_ty = self.typeOf(ty_op.operand);
890 const operand = try self.resolveInst(ty_op.operand);
891 const info_a = operand_ty.intInfo(mod);
892 const info_b = self.typeOfIndex(inst).intInfo(mod);
893 if (info_a.signedness != info_b.signedness)
894 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
1708 const result: MCValue = result: {
1709 const src_int_info = src_ty.intInfo(zcu);
1710 const dst_int_info = dst_ty.intInfo(zcu);
8951711
896 if (info_a.bits == info_b.bits)
897 return self.finishAir(inst, operand, .{ ty_op.operand, .none, .none });
1712 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;
8981713
899 return self.fail("TODO implement intCast for {}", .{self.target.cpu.arch});
900 // return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1714 const src_mcv = try self.resolveInst(ty_op.operand);
1715
1716 const src_storage_bits: u16 = switch (src_mcv) {
1717 .register => 64,
1718 .load_frame => src_int_info.bits,
1719 else => return self.fail("airIntCast from {s}", .{@tagName(src_mcv)}),
1720 };
1721
1722 const dst_mcv = if (dst_int_info.bits <= src_storage_bits and
1723 math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==
1724 math.divCeil(u32, src_storage_bits, 64) catch unreachable and
1725 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
1726 const dst_mcv = try self.allocRegOrMem(inst, true);
1727 try self.genCopy(min_ty, dst_mcv, src_mcv);
1728 break :dst dst_mcv;
1729 };
1730
1731 if (dst_int_info.bits <= src_int_info.bits)
1732 break :result dst_mcv;
1733
1734 if (dst_int_info.bits > 64 or src_int_info.bits > 64)
1735 break :result null; // TODO
1736
1737 break :result dst_mcv;
1738 } orelse return self.fail("TODO implement airIntCast from {} to {}", .{
1739 src_ty.fmt(zcu), dst_ty.fmt(zcu),
1740 });
1741
1742 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
9011743}
9021744
9031745fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
9041746 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9051747 if (self.liveness.isUnused(inst))
906 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
1748 return self.finishAir(inst, .unreach, .{ ty_op.operand, .none, .none });
9071749
9081750 const operand = try self.resolveInst(ty_op.operand);
9091751 _ = operand;
......@@ -914,130 +1756,169 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
9141756fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
9151757 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
9161758 const operand = try self.resolveInst(un_op);
917 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else operand;
1759 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else operand;
9181760 return self.finishAir(inst, result, .{ un_op, .none, .none });
9191761}
9201762
9211763fn airNot(self: *Self, inst: Air.Inst.Index) !void {
9221764 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
923 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement NOT for {}", .{self.target.cpu.arch});
924 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
925}
1765 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
1766 const zcu = self.bin_file.comp.module.?;
9261767
927fn airMin(self: *Self, inst: Air.Inst.Index) !void {
928 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
929 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement min for {}", .{self.target.cpu.arch});
930 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
931}
1768 const operand = try self.resolveInst(ty_op.operand);
1769 const ty = self.typeOf(ty_op.operand);
9321770
933fn airMax(self: *Self, inst: Air.Inst.Index) !void {
934 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
935 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement max for {}", .{self.target.cpu.arch});
936 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
937}
1771 switch (ty.zigTypeTag(zcu)) {
1772 .Bool => {
1773 const operand_reg = blk: {
1774 if (operand == .register) break :blk operand.register;
1775 break :blk try self.copyToTmpRegister(ty, operand);
1776 };
9381777
939fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
940 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
941 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
942 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch});
943 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1778 const dst_reg: Register =
1779 if (self.reuseOperand(inst, ty_op.operand, 0, operand) and operand == .register)
1780 operand.register
1781 else
1782 try self.register_manager.allocReg(inst, gp);
1783
1784 _ = try self.addInst(.{
1785 .tag = .pseudo,
1786 .ops = .pseudo_not,
1787 .data = .{
1788 .rr = .{
1789 .rs = operand_reg,
1790 .rd = dst_reg,
1791 },
1792 },
1793 });
1794
1795 break :result .{ .register = dst_reg };
1796 },
1797 .Int => return self.fail("TODO: airNot ints", .{}),
1798 else => unreachable,
1799 }
1800 };
1801 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
9441802}
9451803
946/// Don't call this function directly. Use binOp instead.
947///
948/// Calling this function signals an intention to generate a Mir
949/// instruction of the form
950///
951/// op dest, lhs, rhs
952///
953/// Asserts that generating an instruction of that form is possible.
954fn binOpRegister(
1804fn airMinMax(
9551805 self: *Self,
956 tag: Air.Inst.Tag,
957 maybe_inst: ?Air.Inst.Index,
958 lhs: MCValue,
959 rhs: MCValue,
960 lhs_ty: Type,
961 rhs_ty: Type,
962) !MCValue {
963 const lhs_is_register = lhs == .register;
964 const rhs_is_register = rhs == .register;
1806 inst: Air.Inst.Index,
1807 comptime tag: enum {
1808 max,
1809 min,
1810 },
1811) !void {
1812 const zcu = self.bin_file.comp.module.?;
1813 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
9651814
966 const lhs_lock: ?RegisterLock = if (lhs_is_register)
967 self.register_manager.lockReg(lhs.register)
968 else
969 null;
970 defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg);
1815 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
1816 const lhs = try self.resolveInst(bin_op.lhs);
1817 const rhs = try self.resolveInst(bin_op.rhs);
1818 const lhs_ty = self.typeOf(bin_op.lhs);
1819 const rhs_ty = self.typeOf(bin_op.rhs);
9711820
972 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
1821 const int_info = lhs_ty.intInfo(zcu);
9731822
974 const lhs_reg = if (lhs_is_register) lhs.register else blk: {
975 const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {
976 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
977 break :inst bin_op.lhs.toIndex().?;
978 } else null;
1823 if (int_info.bits > 64) return self.fail("TODO: > 64 bit @min", .{});
9791824
980 const reg = try self.register_manager.allocReg(track_inst, gp);
1825 const lhs_reg, const lhs_lock = blk: {
1826 if (lhs == .register) break :blk .{ lhs.register, null };
9811827
982 if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg });
1828 const lhs_reg, const lhs_lock = try self.allocReg();
1829 try self.genSetReg(lhs_ty, lhs_reg, lhs);
1830 break :blk .{ lhs_reg, lhs_lock };
1831 };
1832 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
9831833
984 break :blk reg;
985 };
986 const new_lhs_lock = self.register_manager.lockReg(lhs_reg);
987 defer if (new_lhs_lock) |reg| self.register_manager.unlockReg(reg);
1834 const rhs_reg, const rhs_lock = blk: {
1835 if (rhs == .register) break :blk .{ rhs.register, null };
9881836
989 const rhs_reg = if (rhs_is_register) rhs.register else blk: {
990 const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {
991 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
992 break :inst bin_op.rhs.toIndex().?;
993 } else null;
1837 const rhs_reg, const rhs_lock = try self.allocReg();
1838 try self.genSetReg(rhs_ty, rhs_reg, rhs);
1839 break :blk .{ rhs_reg, rhs_lock };
1840 };
1841 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
9941842
995 const reg = try self.register_manager.allocReg(track_inst, gp);
1843 const mask_reg, const mask_lock = try self.allocReg();
1844 defer self.register_manager.unlockReg(mask_lock);
9961845
997 if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg });
1846 const result_reg, const result_lock = try self.allocReg();
1847 defer self.register_manager.unlockReg(result_lock);
9981848
999 break :blk reg;
1000 };
1001 const new_rhs_lock = self.register_manager.lockReg(rhs_reg);
1002 defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);
1849 _ = try self.addInst(.{
1850 .tag = if (int_info.signedness == .unsigned) .sltu else .slt,
1851 .ops = .rrr,
1852 .data = .{ .r_type = .{
1853 .rd = mask_reg,
1854 .rs1 = lhs_reg,
1855 .rs2 = rhs_reg,
1856 } },
1857 });
10031858
1004 const dest_reg = if (maybe_inst) |inst| blk: {
1005 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1859 _ = try self.addInst(.{
1860 .tag = .sub,
1861 .ops = .rrr,
1862 .data = .{ .r_type = .{
1863 .rd = mask_reg,
1864 .rs1 = .zero,
1865 .rs2 = mask_reg,
1866 } },
1867 });
10061868
1007 if (lhs_is_register and self.reuseOperand(inst, bin_op.lhs, 0, lhs)) {
1008 break :blk lhs_reg;
1009 } else if (rhs_is_register and self.reuseOperand(inst, bin_op.rhs, 1, rhs)) {
1010 break :blk rhs_reg;
1011 } else {
1012 break :blk try self.register_manager.allocReg(inst, gp);
1013 }
1014 } else try self.register_manager.allocReg(null, gp);
1869 _ = try self.addInst(.{
1870 .tag = .xor,
1871 .ops = .rrr,
1872 .data = .{ .r_type = .{
1873 .rd = result_reg,
1874 .rs1 = lhs_reg,
1875 .rs2 = rhs_reg,
1876 } },
1877 });
10151878
1016 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
1017 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
1879 _ = try self.addInst(.{
1880 .tag = .@"and",
1881 .ops = .rrr,
1882 .data = .{ .r_type = .{
1883 .rd = mask_reg,
1884 .rs1 = result_reg,
1885 .rs2 = mask_reg,
1886 } },
1887 });
10181888
1019 const mir_tag: Mir.Inst.Tag = switch (tag) {
1020 .add => .add,
1021 .sub => .sub,
1022 else => unreachable,
1023 };
1024 const mir_data: Mir.Inst.Data = switch (tag) {
1025 .add,
1026 .sub,
1027 => .{ .r_type = .{
1028 .rd = dest_reg,
1029 .rs1 = lhs_reg,
1030 .rs2 = rhs_reg,
1031 } },
1032 else => unreachable,
1889 _ = try self.addInst(.{
1890 .tag = .xor,
1891 .ops = .rrr,
1892 .data = .{ .r_type = .{
1893 .rd = result_reg,
1894 .rs1 = if (tag == .min) rhs_reg else lhs_reg,
1895 .rs2 = mask_reg,
1896 } },
1897 });
1898
1899 break :result .{ .register = result_reg };
10331900 };
1901 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1902}
10341903
1035 _ = try self.addInst(.{
1036 .tag = mir_tag,
1037 .data = mir_data,
1038 });
1904fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1905 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1906 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1907 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch});
1908 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1909}
10391910
1040 return MCValue{ .register = dest_reg };
1911fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1912 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1913 const lhs = try self.resolveInst(bin_op.lhs);
1914 const rhs = try self.resolveInst(bin_op.rhs);
1915 const lhs_ty = self.typeOf(bin_op.lhs);
1916 const rhs_ty = self.typeOf(bin_op.rhs);
1917
1918 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
1919 break :result try self.binOp(tag, lhs, lhs_ty, rhs, rhs_ty);
1920 };
1921 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
10411922}
10421923
10431924/// For all your binary operation needs, this function will generate
......@@ -1052,48 +1933,57 @@ fn binOpRegister(
10521933/// looks at the lhs and rhs and determines which kind of lowering
10531934/// would be best suitable and then delegates the lowering to other
10541935/// functions.
1936///
1937/// `maybe_inst` **needs** to be a bin_op, make sure of that.
10551938fn binOp(
10561939 self: *Self,
10571940 tag: Air.Inst.Tag,
1058 maybe_inst: ?Air.Inst.Index,
10591941 lhs: MCValue,
1060 rhs: MCValue,
10611942 lhs_ty: Type,
1943 rhs: MCValue,
10621944 rhs_ty: Type,
10631945) InnerError!MCValue {
1064 const mod = self.bin_file.comp.module.?;
1946 const zcu = self.bin_file.comp.module.?;
1947
10651948 switch (tag) {
10661949 // Arithmetic operations on integers and floats
10671950 .add,
10681951 .sub,
1952 .mul,
1953 .cmp_eq,
1954 .cmp_neq,
1955 .cmp_gt,
1956 .cmp_gte,
1957 .cmp_lt,
1958 .cmp_lte,
10691959 => {
1070 switch (lhs_ty.zigTypeTag(mod)) {
1960 switch (lhs_ty.zigTypeTag(zcu)) {
10711961 .Float => return self.fail("TODO binary operations on floats", .{}),
10721962 .Vector => return self.fail("TODO binary operations on vectors", .{}),
10731963 .Int => {
1074 assert(lhs_ty.eql(rhs_ty, mod));
1075 const int_info = lhs_ty.intInfo(mod);
1964 assert(lhs_ty.eql(rhs_ty, zcu));
1965 const int_info = lhs_ty.intInfo(zcu);
10761966 if (int_info.bits <= 64) {
1077 // TODO immediate operands
1078 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1967 return self.binOpRegister(tag, lhs, lhs_ty, rhs, rhs_ty);
10791968 } else {
10801969 return self.fail("TODO binary operations on int with bits > 64", .{});
10811970 }
10821971 },
1083 else => unreachable,
1972 else => |x| return self.fail("TOOD: binOp {s}", .{@tagName(x)}),
10841973 }
10851974 },
1975
10861976 .ptr_add,
10871977 .ptr_sub,
10881978 => {
1089 switch (lhs_ty.zigTypeTag(mod)) {
1979 switch (lhs_ty.zigTypeTag(zcu)) {
10901980 .Pointer => {
10911981 const ptr_ty = lhs_ty;
1092 const elem_ty = switch (ptr_ty.ptrSize(mod)) {
1093 .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type
1094 else => ptr_ty.childType(mod),
1982 const elem_ty = switch (ptr_ty.ptrSize(zcu)) {
1983 .One => ptr_ty.childType(zcu).childType(zcu), // ptr to array, so get array element type
1984 else => ptr_ty.childType(zcu),
10951985 };
1096 const elem_size = elem_ty.abiSize(mod);
1986 const elem_size = elem_ty.abiSize(zcu);
10971987
10981988 if (elem_size == 1) {
10991989 const base_tag: Air.Inst.Tag = switch (tag) {
......@@ -1102,27 +1992,167 @@ fn binOp(
11021992 else => unreachable,
11031993 };
11041994
1105 return try self.binOpRegister(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1995 return try self.binOpRegister(base_tag, lhs, lhs_ty, rhs, rhs_ty);
11061996 } else {
1107 return self.fail("TODO ptr_add with elem_size > 1", .{});
1997 const offset = try self.binOp(
1998 .mul,
1999 rhs,
2000 Type.usize,
2001 .{ .immediate = elem_size },
2002 Type.usize,
2003 );
2004
2005 const addr = try self.binOp(
2006 tag,
2007 lhs,
2008 Type.manyptr_u8,
2009 offset,
2010 Type.usize,
2011 );
2012 return addr;
11082013 }
11092014 },
11102015 else => unreachable,
11112016 }
11122017 },
1113 else => unreachable,
2018
2019 // These instructions have unsymteric bit sizes on RHS and LHS.
2020 .shr,
2021 .shl,
2022 => {
2023 switch (lhs_ty.zigTypeTag(zcu)) {
2024 .Float => return self.fail("TODO binary operations on floats", .{}),
2025 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2026 .Int => {
2027 const int_info = lhs_ty.intInfo(zcu);
2028 if (int_info.bits <= 64) {
2029 return self.binOpRegister(tag, lhs, lhs_ty, rhs, rhs_ty);
2030 } else {
2031 return self.fail("TODO binary operations on int with bits > 64", .{});
2032 }
2033 },
2034 else => unreachable,
2035 }
2036 },
2037 else => return self.fail("TODO binOp {}", .{tag}),
11142038 }
11152039}
2040/// Don't call this function directly. Use binOp instead.
2041///
2042/// Calling this function signals an intention to generate a Mir
2043/// instruction of the form
2044///
2045/// op dest, lhs, rhs
2046///
2047/// Asserts that generating an instruction of that form is possible.
2048fn binOpRegister(
2049 self: *Self,
2050 tag: Air.Inst.Tag,
2051 lhs: MCValue,
2052 lhs_ty: Type,
2053 rhs: MCValue,
2054 rhs_ty: Type,
2055) !MCValue {
2056 const lhs_reg, const lhs_lock = blk: {
2057 if (lhs == .register) break :blk .{ lhs.register, null };
11162058
1117fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1118 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1119 const lhs = try self.resolveInst(bin_op.lhs);
1120 const rhs = try self.resolveInst(bin_op.rhs);
1121 const lhs_ty = self.typeOf(bin_op.lhs);
1122 const rhs_ty = self.typeOf(bin_op.rhs);
2059 const lhs_reg, const lhs_lock = try self.allocReg();
2060 try self.genSetReg(lhs_ty, lhs_reg, lhs);
2061 break :blk .{ lhs_reg, lhs_lock };
2062 };
2063 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
11232064
1124 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
1125 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
2065 const rhs_reg, const rhs_lock = blk: {
2066 if (rhs == .register) break :blk .{ rhs.register, null };
2067
2068 const rhs_reg, const rhs_lock = try self.allocReg();
2069 try self.genSetReg(rhs_ty, rhs_reg, rhs);
2070 break :blk .{ rhs_reg, rhs_lock };
2071 };
2072 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
2073
2074 const dest_reg, const dest_lock = try self.allocReg();
2075 defer self.register_manager.unlockReg(dest_lock);
2076
2077 const mir_tag: Mir.Inst.Tag = switch (tag) {
2078 .add => .add,
2079 .sub => .sub,
2080 .mul => .mul,
2081
2082 .shl => .sllw,
2083 .shr => .srlw,
2084
2085 .cmp_eq,
2086 .cmp_neq,
2087 .cmp_gt,
2088 .cmp_gte,
2089 .cmp_lt,
2090 .cmp_lte,
2091 => .pseudo,
2092
2093 else => return self.fail("TODO: binOpRegister {s}", .{@tagName(tag)}),
2094 };
2095
2096 switch (mir_tag) {
2097 .add,
2098 .sub,
2099 .mul,
2100 .sllw,
2101 .srlw,
2102 => {
2103 _ = try self.addInst(.{
2104 .tag = mir_tag,
2105 .ops = .rrr,
2106 .data = .{
2107 .r_type = .{
2108 .rd = dest_reg,
2109 .rs1 = lhs_reg,
2110 .rs2 = rhs_reg,
2111 },
2112 },
2113 });
2114 },
2115
2116 .pseudo => {
2117 const pseudo_op = switch (tag) {
2118 .cmp_eq,
2119 .cmp_neq,
2120 .cmp_gt,
2121 .cmp_gte,
2122 .cmp_lt,
2123 .cmp_lte,
2124 => .pseudo_compare,
2125 else => unreachable,
2126 };
2127
2128 _ = try self.addInst(.{
2129 .tag = .pseudo,
2130 .ops = pseudo_op,
2131 .data = .{
2132 .compare = .{
2133 .rd = dest_reg,
2134 .rs1 = lhs_reg,
2135 .rs2 = rhs_reg,
2136 .op = switch (tag) {
2137 .cmp_eq => .eq,
2138 .cmp_neq => .neq,
2139 .cmp_gt => .gt,
2140 .cmp_gte => .gte,
2141 .cmp_lt => .lt,
2142 .cmp_lte => .lte,
2143 else => unreachable,
2144 },
2145 },
2146 },
2147 });
2148 },
2149
2150 else => unreachable,
2151 }
2152
2153 // generate the struct for OF checks
2154
2155 return MCValue{ .register = dest_reg };
11262156}
11272157
11282158fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
......@@ -1133,55 +2163,150 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
11332163 const lhs_ty = self.typeOf(bin_op.lhs);
11342164 const rhs_ty = self.typeOf(bin_op.rhs);
11352165
1136 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
2166 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2167 break :result try self.binOp(tag, lhs, lhs_ty, rhs, rhs_ty);
2168 };
11372169 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11382170}
11392171
11402172fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {
11412173 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1142 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});
2174 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});
11432175 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11442176}
11452177
11462178fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
11472179 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1148 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
2180 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
11492181 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11502182}
11512183
11522184fn airSubWrap(self: *Self, inst: Air.Inst.Index) !void {
11532185 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1154 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement subwrap for {}", .{self.target.cpu.arch});
2186 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2187 // RISCV arthemtic instructions already wrap, so this is simply a sub binOp with
2188 // no overflow checks.
2189 const lhs = try self.resolveInst(bin_op.lhs);
2190 const rhs = try self.resolveInst(bin_op.rhs);
2191 const lhs_ty = self.typeOf(bin_op.lhs);
2192 const rhs_ty = self.typeOf(bin_op.rhs);
2193
2194 break :result try self.binOp(.sub, lhs, lhs_ty, rhs, rhs_ty);
2195 };
11552196 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11562197}
11572198
11582199fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
11592200 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1160 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
2201 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
11612202 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11622203}
11632204
11642205fn airMul(self: *Self, inst: Air.Inst.Index) !void {
11652206 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1166 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul for {}", .{self.target.cpu.arch});
2207 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement mul for {}", .{self.target.cpu.arch});
11672208 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11682209}
11692210
11702211fn airMulWrap(self: *Self, inst: Air.Inst.Index) !void {
11712212 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1172 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch});
2213 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch});
11732214 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11742215}
11752216
11762217fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
11772218 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1178 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
2219 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
11792220 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
11802221}
11812222
11822223fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1183 _ = inst;
1184 return self.fail("TODO implement airAddWithOverflow for {}", .{self.target.cpu.arch});
2224 const zcu = self.bin_file.comp.module.?;
2225 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2226 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2227
2228 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2229 const lhs = try self.resolveInst(extra.lhs);
2230 const rhs = try self.resolveInst(extra.rhs);
2231 const lhs_ty = self.typeOf(extra.lhs);
2232 const rhs_ty = self.typeOf(extra.rhs);
2233
2234 const int_info = lhs_ty.intInfo(zcu);
2235
2236 const tuple_ty = self.typeOfIndex(inst);
2237 const result_mcv = try self.allocRegOrMem(inst, false);
2238 const offset = result_mcv.load_frame;
2239
2240 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
2241 const add_result = try self.binOp(.add, lhs, lhs_ty, rhs, rhs_ty);
2242 const add_result_reg = try self.copyToTmpRegister(lhs_ty, add_result);
2243 const add_result_reg_lock = self.register_manager.lockRegAssumeUnused(add_result_reg);
2244 defer self.register_manager.unlockReg(add_result_reg_lock);
2245
2246 const shift_amount: u6 = @intCast(Type.usize.bitSize(zcu) - int_info.bits);
2247
2248 const shift_reg, const shift_lock = try self.allocReg();
2249 defer self.register_manager.unlockReg(shift_lock);
2250
2251 _ = try self.addInst(.{
2252 .tag = .slli,
2253 .ops = .rri,
2254 .data = .{
2255 .i_type = .{
2256 .rd = shift_reg,
2257 .rs1 = add_result_reg,
2258 .imm12 = Immediate.s(shift_amount),
2259 },
2260 },
2261 });
2262
2263 _ = try self.addInst(.{
2264 .tag = if (int_info.signedness == .unsigned) .srli else .srai,
2265 .ops = .rri,
2266 .data = .{
2267 .i_type = .{
2268 .rd = shift_reg,
2269 .rs1 = shift_reg,
2270 .imm12 = Immediate.s(shift_amount),
2271 },
2272 },
2273 });
2274
2275 const add_result_frame: FrameAddr = .{
2276 .index = offset.index,
2277 .off = offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, zcu))),
2278 };
2279 try self.genSetStack(
2280 lhs_ty,
2281 add_result_frame,
2282 add_result,
2283 );
2284
2285 const overflow_mcv = try self.binOp(
2286 .cmp_neq,
2287 .{ .register = shift_reg },
2288 lhs_ty,
2289 .{ .register = add_result_reg },
2290 lhs_ty,
2291 );
2292
2293 const overflow_frame: FrameAddr = .{
2294 .index = offset.index,
2295 .off = offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(1, zcu))),
2296 };
2297 try self.genSetStack(
2298 Type.u1,
2299 overflow_frame,
2300 overflow_mcv,
2301 );
2302
2303 break :result result_mcv;
2304 } else {
2305 return self.fail("TODO: less than 8 bit or non-pow 2 addition", .{});
2306 }
2307 };
2308
2309 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
11852310}
11862311
11872312fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
......@@ -1190,8 +2315,104 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
11902315}
11912316
11922317fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1193 _ = inst;
1194 return self.fail("TODO implement airMulWithOverflow for {}", .{self.target.cpu.arch});
2318 //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
2319 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2320 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2321 const zcu = self.bin_file.comp.module.?;
2322 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2323 const lhs = try self.resolveInst(extra.lhs);
2324 const rhs = try self.resolveInst(extra.rhs);
2325 const lhs_ty = self.typeOf(extra.lhs);
2326 const rhs_ty = self.typeOf(extra.rhs);
2327
2328 switch (lhs_ty.zigTypeTag(zcu)) {
2329 else => |x| return self.fail("TODO: airMulWithOverflow {s}", .{@tagName(x)}),
2330 .Int => {
2331 assert(lhs_ty.eql(rhs_ty, zcu));
2332 const int_info = lhs_ty.intInfo(zcu);
2333 switch (int_info.bits) {
2334 1...32 => {
2335 if (self.hasFeature(.m)) {
2336 const dest = try self.binOp(.mul, lhs, lhs_ty, rhs, rhs_ty);
2337
2338 const add_result_lock = self.register_manager.lockRegAssumeUnused(dest.register);
2339 defer self.register_manager.unlockReg(add_result_lock);
2340
2341 const tuple_ty = self.typeOfIndex(inst);
2342
2343 // TODO: optimization, set this to true. needs the other struct access stuff to support
2344 // accessing registers.
2345 const result_mcv = try self.allocRegOrMem(inst, false);
2346
2347 const result_off: i32 = @intCast(tuple_ty.structFieldOffset(0, zcu));
2348 const overflow_off: i32 = @intCast(tuple_ty.structFieldOffset(1, zcu));
2349
2350 try self.genSetStack(lhs_ty, result_mcv.offset(result_off).load_frame, dest);
2351
2352 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
2353 if (int_info.signedness == .unsigned) {
2354 switch (int_info.bits) {
2355 1...8 => {
2356 const max_val = std.math.pow(u16, 2, int_info.bits) - 1;
2357
2358 const overflow_reg, const overflow_lock = try self.allocReg();
2359 defer self.register_manager.unlockReg(overflow_lock);
2360
2361 const add_reg, const add_lock = blk: {
2362 if (dest == .register) break :blk .{ dest.register, null };
2363
2364 const add_reg, const add_lock = try self.allocReg();
2365 try self.genSetReg(lhs_ty, add_reg, dest);
2366 break :blk .{ add_reg, add_lock };
2367 };
2368 defer if (add_lock) |lock| self.register_manager.unlockReg(lock);
2369
2370 _ = try self.addInst(.{
2371 .tag = .andi,
2372 .ops = .rri,
2373 .data = .{ .i_type = .{
2374 .rd = overflow_reg,
2375 .rs1 = add_reg,
2376 .imm12 = Immediate.s(max_val),
2377 } },
2378 });
2379
2380 const overflow_mcv = try self.binOp(
2381 .cmp_neq,
2382 .{ .register = overflow_reg },
2383 lhs_ty,
2384 .{ .register = add_reg },
2385 lhs_ty,
2386 );
2387
2388 try self.genSetStack(
2389 lhs_ty,
2390 result_mcv.offset(overflow_off).load_frame,
2391 overflow_mcv,
2392 );
2393
2394 break :result result_mcv;
2395 },
2396
2397 else => return self.fail("TODO: airMulWithOverflow check for size {d}", .{int_info.bits}),
2398 }
2399 } else {
2400 return self.fail("TODO: airMulWithOverflow calculate carry for signed addition", .{});
2401 }
2402 } else {
2403 return self.fail("TODO: airMulWithOverflow with < 8 bits or non-pow of 2", .{});
2404 }
2405 } else {
2406 return self.fail("TODO: emulate mul for targets without M feature", .{});
2407 }
2408 },
2409 else => return self.fail("TODO: airMulWithOverflow larger than 32-bit mul", .{}),
2410 }
2411 },
2412 }
2413 };
2414
2415 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
11952416}
11962417
11972418fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
......@@ -1201,111 +2422,200 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
12012422
12022423fn airDiv(self: *Self, inst: Air.Inst.Index) !void {
12032424 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1204 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement div for {}", .{self.target.cpu.arch});
2425 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement div for {}", .{self.target.cpu.arch});
12052426 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12062427}
12072428
12082429fn airRem(self: *Self, inst: Air.Inst.Index) !void {
12092430 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1210 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement rem for {}", .{self.target.cpu.arch});
2431 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement rem for {}", .{self.target.cpu.arch});
12112432 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12122433}
12132434
12142435fn airMod(self: *Self, inst: Air.Inst.Index) !void {
12152436 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1216 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mod for {}", .{self.target.cpu.arch});
2437 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement zcu for {}", .{self.target.cpu.arch});
12172438 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12182439}
12192440
12202441fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
12212442 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1222 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement bitwise and for {}", .{self.target.cpu.arch});
2443 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement bitwise and for {}", .{self.target.cpu.arch});
12232444 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12242445}
12252446
12262447fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
12272448 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1228 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement bitwise or for {}", .{self.target.cpu.arch});
2449 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement bitwise or for {}", .{self.target.cpu.arch});
12292450 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12302451}
12312452
12322453fn airXor(self: *Self, inst: Air.Inst.Index) !void {
12332454 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1234 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement xor for {}", .{self.target.cpu.arch});
2455 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement xor for {}", .{self.target.cpu.arch});
12352456 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12362457}
12372458
12382459fn airShl(self: *Self, inst: Air.Inst.Index) !void {
12392460 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1240 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl for {}", .{self.target.cpu.arch});
2461 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2462 const lhs = try self.resolveInst(bin_op.lhs);
2463 const rhs = try self.resolveInst(bin_op.rhs);
2464 const lhs_ty = self.typeOf(bin_op.lhs);
2465 const rhs_ty = self.typeOf(bin_op.rhs);
2466
2467 break :result try self.binOp(.shl, lhs, lhs_ty, rhs, rhs_ty);
2468 };
12412469 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12422470}
12432471
12442472fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
12452473 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1246 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch});
2474 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch});
12472475 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12482476}
12492477
12502478fn airShr(self: *Self, inst: Air.Inst.Index) !void {
12512479 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1252 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shr for {}", .{self.target.cpu.arch});
2480 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement shr for {}", .{self.target.cpu.arch});
12532481 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
12542482}
12552483
12562484fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
12572485 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1258 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload for {}", .{self.target.cpu.arch});
2486 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement .optional_payload for {}", .{self.target.cpu.arch});
12592487 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12602488}
12612489
12622490fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
12632491 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1264 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});
2492 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});
12652493 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12662494}
12672495
12682496fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
12692497 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1270 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch});
2498 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch});
12712499 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12722500}
12732501
12742502fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
12752503 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1276 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union error for {}", .{self.target.cpu.arch});
2504 const zcu = self.bin_file.comp.module.?;
2505 const err_union_ty = self.typeOf(ty_op.operand);
2506 const err_ty = err_union_ty.errorUnionSet(zcu);
2507 const payload_ty = err_union_ty.errorUnionPayload(zcu);
2508 const operand = try self.resolveInst(ty_op.operand);
2509
2510 const result: MCValue = result: {
2511 if (err_ty.errorSetIsEmpty(zcu)) {
2512 break :result .{ .immediate = 0 };
2513 }
2514
2515 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2516 break :result operand;
2517 }
2518
2519 const err_off: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu));
2520
2521 switch (operand) {
2522 .register => |reg| {
2523 const eu_lock = self.register_manager.lockReg(reg);
2524 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
2525
2526 var result = try self.copyToNewRegister(inst, operand);
2527
2528 if (err_off > 0) {
2529 result = try self.binOp(
2530 .shr,
2531 result,
2532 err_union_ty,
2533 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
2534 Type.u8,
2535 );
2536 }
2537 break :result result;
2538 },
2539 else => return self.fail("TODO implement unwrap_err_err for {}", .{operand}),
2540 }
2541 };
2542
12772543 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12782544}
12792545
12802546fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
12812547 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1282 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union payload for {}", .{self.target.cpu.arch});
2548 const operand_ty = self.typeOf(ty_op.operand);
2549 const operand = try self.resolveInst(ty_op.operand);
2550 const result = try self.genUnwrapErrUnionPayloadMir(operand_ty, operand);
12832551 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12842552}
12852553
2554fn genUnwrapErrUnionPayloadMir(
2555 self: *Self,
2556 err_union_ty: Type,
2557 err_union: MCValue,
2558) !MCValue {
2559 const zcu = self.bin_file.comp.module.?;
2560 const payload_ty = err_union_ty.errorUnionPayload(zcu);
2561
2562 const result: MCValue = result: {
2563 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
2564
2565 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
2566 switch (err_union) {
2567 .load_frame => |frame_addr| break :result .{ .load_frame = .{
2568 .index = frame_addr.index,
2569 .off = frame_addr.off + payload_off,
2570 } },
2571 .register => |reg| {
2572 const eu_lock = self.register_manager.lockReg(reg);
2573 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
2574
2575 var result: MCValue = .{ .register = try self.copyToTmpRegister(err_union_ty, err_union) };
2576
2577 if (payload_off > 0) {
2578 result = try self.binOp(
2579 .shr,
2580 result,
2581 err_union_ty,
2582 .{ .immediate = @as(u6, @intCast(payload_off * 8)) },
2583 Type.u8,
2584 );
2585 }
2586
2587 break :result result;
2588 },
2589 else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {}", .{err_union}),
2590 }
2591 };
2592
2593 return result;
2594}
2595
12862596// *(E!T) -> E
12872597fn airUnwrapErrErrPtr(self: *Self, inst: Air.Inst.Index) !void {
12882598 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1289 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union error ptr for {}", .{self.target.cpu.arch});
2599 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement unwrap error union error ptr for {}", .{self.target.cpu.arch});
12902600 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12912601}
12922602
12932603// *(E!T) -> *T
12942604fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
12952605 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1296 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union payload ptr for {}", .{self.target.cpu.arch});
2606 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement unwrap error union payload ptr for {}", .{self.target.cpu.arch});
12972607 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12982608}
12992609
13002610fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
13012611 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1302 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
2612 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
13032613 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13042614}
13052615
13062616fn airErrReturnTrace(self: *Self, inst: Air.Inst.Index) !void {
13072617 const result: MCValue = if (self.liveness.isUnused(inst))
1308 .dead
2618 .unreach
13092619 else
13102620 return self.fail("TODO implement airErrReturnTrace for {}", .{self.target.cpu.arch});
13112621 return self.finishAir(inst, result, .{ .none, .none, .none });
......@@ -1323,12 +2633,12 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
13232633
13242634fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
13252635 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1326 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1327 const mod = self.bin_file.comp.module.?;
2636 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2637 const zcu = self.bin_file.comp.module.?;
13282638 const optional_ty = self.typeOfIndex(inst);
13292639
13302640 // Optional with a zero-bit payload type is just a boolean true
1331 if (optional_ty.abiSize(mod) == 1)
2641 if (optional_ty.abiSize(zcu) == 1)
13322642 break :result MCValue{ .immediate = 1 };
13332643
13342644 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});
......@@ -1339,72 +2649,251 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
13392649/// T to E!T
13402650fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
13412651 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1342 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch});
2652 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch});
13432653 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13442654}
13452655
13462656/// E to E!T
13472657fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2658 const zcu = self.bin_file.comp.module.?;
13482659 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1349 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion error for {}", .{self.target.cpu.arch});
2660
2661 const eu_ty = ty_op.ty.toType();
2662 const pl_ty = eu_ty.errorUnionPayload(zcu);
2663 const err_ty = eu_ty.errorUnionSet(zcu);
2664
2665 const result: MCValue = result: {
2666 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try self.resolveInst(ty_op.operand);
2667
2668 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
2669 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
2670 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu));
2671 try self.genSetStack(pl_ty, .{ .index = frame_index, .off = pl_off }, .undef);
2672 const operand = try self.resolveInst(ty_op.operand);
2673 try self.genSetStack(err_ty, .{ .index = frame_index, .off = err_off }, operand);
2674 break :result .{ .load_frame = .{ .index = frame_index } };
2675 };
13502676 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13512677}
13522678
2679fn airTry(self: *Self, inst: Air.Inst.Index) !void {
2680 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
2681 const extra = self.air.extraData(Air.Try, pl_op.payload);
2682 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
2683 const operand_ty = self.typeOf(pl_op.operand);
2684 const result = try self.genTry(inst, pl_op.operand, body, operand_ty, false);
2685 return self.finishAir(inst, result, .{ .none, .none, .none });
2686}
2687
2688fn genTry(
2689 self: *Self,
2690 inst: Air.Inst.Index,
2691 operand: Air.Inst.Ref,
2692 body: []const Air.Inst.Index,
2693 operand_ty: Type,
2694 operand_is_ptr: bool,
2695) !MCValue {
2696 _ = operand_is_ptr;
2697
2698 const liveness_cond_br = self.liveness.getCondBr(inst);
2699
2700 const operand_mcv = try self.resolveInst(operand);
2701 const is_err_mcv = try self.isErr(null, operand_ty, operand_mcv);
2702
2703 // A branch to the false section. Uses beq. 1 is the default "true" state.
2704 const reloc = try self.condBr(Type.anyerror, is_err_mcv);
2705
2706 if (self.liveness.operandDies(inst, 0)) {
2707 if (operand.toIndex()) |operand_inst| try self.processDeath(operand_inst);
2708 }
2709
2710 self.scope_generation += 1;
2711 const state = try self.saveState();
2712
2713 for (liveness_cond_br.else_deaths) |death| try self.processDeath(death);
2714 try self.genBody(body);
2715 try self.restoreState(state, &.{}, .{
2716 .emit_instructions = false,
2717 .update_tracking = true,
2718 .resurrect = true,
2719 .close_scope = true,
2720 });
2721
2722 self.performReloc(reloc);
2723
2724 for (liveness_cond_br.then_deaths) |death| try self.processDeath(death);
2725
2726 const result = if (self.liveness.isUnused(inst))
2727 .unreach
2728 else
2729 try self.genUnwrapErrUnionPayloadMir(operand_ty, operand_mcv);
2730
2731 return result;
2732}
2733
13532734fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
13542735 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1355 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});
2736 const result = result: {
2737 const src_mcv = try self.resolveInst(ty_op.operand);
2738 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
2739
2740 const dst_mcv = try self.allocRegOrMem(inst, true);
2741 const dst_ty = self.typeOfIndex(inst);
2742 try self.genCopy(dst_ty, dst_mcv, src_mcv);
2743 break :result dst_mcv;
2744 };
13562745 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13572746}
13582747
13592748fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
13602749 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1361 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_len for {}", .{self.target.cpu.arch});
2750 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2751 const src_mcv = try self.resolveInst(ty_op.operand);
2752 switch (src_mcv) {
2753 .load_frame => |frame_addr| {
2754 const len_mcv: MCValue = .{ .load_frame = .{
2755 .index = frame_addr.index,
2756 .off = frame_addr.off + 8,
2757 } };
2758 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result len_mcv;
2759
2760 const dst_mcv = try self.allocRegOrMem(inst, true);
2761 try self.genCopy(Type.usize, dst_mcv, len_mcv);
2762 break :result dst_mcv;
2763 },
2764 .register_pair => |pair| {
2765 const len_mcv: MCValue = .{ .register = pair[1] };
2766
2767 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result len_mcv;
2768
2769 const dst_mcv = try self.allocRegOrMem(inst, true);
2770 try self.genCopy(Type.usize, dst_mcv, len_mcv);
2771 break :result dst_mcv;
2772 },
2773 else => return self.fail("TODO airSliceLen for {}", .{src_mcv}),
2774 }
2775 };
13622776 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13632777}
13642778
13652779fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
13662780 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1367 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});
2781 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});
13682782 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13692783}
13702784
13712785fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
13722786 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1373 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});
2787 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});
13742788 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
13752789}
13762790
13772791fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2792 const zcu = self.bin_file.comp.module.?;
13782793 const is_volatile = false; // TODO
13792794 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1380 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_elem_val for {}", .{self.target.cpu.arch});
2795
2796 if (!is_volatile and self.liveness.isUnused(inst)) return self.finishAir(
2797 inst,
2798 .unreach,
2799 .{ bin_op.lhs, bin_op.rhs, .none },
2800 );
2801 const result: MCValue = result: {
2802 const slice_mcv = try self.resolveInst(bin_op.lhs);
2803 const index_mcv = try self.resolveInst(bin_op.rhs);
2804
2805 const slice_ty = self.typeOf(bin_op.lhs);
2806
2807 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
2808
2809 const index_lock: ?RegisterLock = if (index_mcv == .register)
2810 self.register_manager.lockRegAssumeUnused(index_mcv.register)
2811 else
2812 null;
2813 defer if (index_lock) |reg| self.register_manager.unlockReg(reg);
2814
2815 const base_mcv: MCValue = switch (slice_mcv) {
2816 .load_frame,
2817 .load_symbol,
2818 => .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, slice_mcv) },
2819 else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}),
2820 };
2821
2822 const dest = try self.allocRegOrMem(inst, true);
2823 const addr = try self.binOp(.ptr_add, base_mcv, slice_ptr_field_type, index_mcv, Type.usize);
2824 try self.load(dest, addr, slice_ptr_field_type);
2825
2826 break :result dest;
2827 };
13812828 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
13822829}
13832830
13842831fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
13852832 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
13862833 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1387 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_elem_ptr for {}", .{self.target.cpu.arch});
2834 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement slice_elem_ptr for {}", .{self.target.cpu.arch});
13882835 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
13892836}
13902837
13912838fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
2839 const zcu = self.bin_file.comp.module.?;
13922840 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1393 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement array_elem_val for {}", .{self.target.cpu.arch});
2841 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2842 const array_ty = self.typeOf(bin_op.lhs);
2843 const array_mcv = try self.resolveInst(bin_op.lhs);
2844
2845 const index_mcv = try self.resolveInst(bin_op.rhs);
2846 const index_ty = self.typeOf(bin_op.rhs);
2847
2848 const elem_ty = array_ty.childType(zcu);
2849 const elem_abi_size = elem_ty.abiSize(zcu);
2850
2851 const addr_reg, const addr_reg_lock = try self.allocReg();
2852 defer self.register_manager.unlockReg(addr_reg_lock);
2853
2854 switch (array_mcv) {
2855 .register => {
2856 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, zcu));
2857 try self.genSetStack(array_ty, .{ .index = frame_index }, array_mcv);
2858 try self.genSetReg(Type.usize, addr_reg, .{ .lea_frame = .{ .index = frame_index } });
2859 },
2860 .load_frame => |frame_addr| {
2861 try self.genSetReg(Type.usize, addr_reg, .{ .lea_frame = frame_addr });
2862 },
2863 else => try self.genSetReg(Type.usize, addr_reg, array_mcv.address()),
2864 }
2865
2866 const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size);
2867 const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
2868 defer self.register_manager.unlockReg(offset_lock);
2869
2870 const dst_mcv = try self.allocRegOrMem(inst, false);
2871 _ = try self.addInst(.{
2872 .tag = .add,
2873 .ops = .rrr,
2874 .data = .{ .r_type = .{
2875 .rd = addr_reg,
2876 .rs1 = offset_reg,
2877 .rs2 = addr_reg,
2878 } },
2879 });
2880 try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } });
2881 break :result dst_mcv;
2882 };
13942883 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
13952884}
13962885
13972886fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
13982887 const is_volatile = false; // TODO
13992888 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1400 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});
2889 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});
14012890 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
14022891}
14032892
14042893fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
14052894 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
14062895 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1407 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch});
2896 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch});
14082897 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
14092898}
14102899
......@@ -1417,124 +2906,234 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
14172906
14182907fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
14192908 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1420 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch});
2909 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch});
14212910 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14222911}
14232912
14242913fn airClz(self: *Self, inst: Air.Inst.Index) !void {
14252914 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1426 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airClz for {}", .{self.target.cpu.arch});
2915 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airClz for {}", .{self.target.cpu.arch});
14272916 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14282917}
14292918
14302919fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
14312920 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1432 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCtz for {}", .{self.target.cpu.arch});
2921 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2922 const operand = try self.resolveInst(ty_op.operand);
2923 const operand_ty = self.typeOf(ty_op.operand);
2924
2925 const dest_reg = try self.register_manager.allocReg(inst, gp);
2926
2927 const source_reg, const source_lock = blk: {
2928 if (operand == .register) break :blk .{ operand.register, null };
2929
2930 const source_reg, const source_lock = try self.allocReg();
2931 try self.genSetReg(operand_ty, source_reg, operand);
2932 break :blk .{ source_reg, source_lock };
2933 };
2934 defer if (source_lock) |lock| self.register_manager.unlockReg(lock);
2935
2936 // TODO: the B extension for RISCV should have the ctz instruction, and we should use it.
2937
2938 try self.ctz(source_reg, dest_reg, operand_ty);
2939
2940 break :result .{ .register = dest_reg };
2941 };
14332942 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14342943}
14352944
2945fn ctz(self: *Self, src: Register, dst: Register, ty: Type) !void {
2946 const zcu = self.bin_file.comp.module.?;
2947 const length = (ty.abiSize(zcu) * 8) - 1;
2948
2949 const count_reg, const count_lock = try self.allocReg();
2950 defer self.register_manager.unlockReg(count_lock);
2951
2952 const len_reg, const len_lock = try self.allocReg();
2953 defer self.register_manager.unlockReg(len_lock);
2954
2955 try self.genSetReg(Type.usize, count_reg, .{ .immediate = 0 });
2956 try self.genSetReg(Type.usize, len_reg, .{ .immediate = length });
2957
2958 _ = src;
2959 _ = dst;
2960
2961 return self.fail("TODO: finish ctz", .{});
2962}
2963
14362964fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
14372965 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1438 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch});
2966 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch});
14392967 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14402968}
14412969
14422970fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
2971 const zcu = self.bin_file.comp.module.?;
14432972 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1444 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airAbs for {}", .{self.target.cpu.arch});
2973 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
2974 const ty = self.typeOf(ty_op.operand);
2975 const scalar_ty = ty.scalarType(zcu);
2976 const operand = try self.resolveInst(ty_op.operand);
2977
2978 switch (scalar_ty.zigTypeTag(zcu)) {
2979 .Int => if (ty.zigTypeTag(zcu) == .Vector) {
2980 return self.fail("TODO implement airAbs for {}", .{ty.fmt(zcu)});
2981 } else {
2982 const int_bits = ty.intInfo(zcu).bits;
2983
2984 if (int_bits > 32) {
2985 return self.fail("TODO: airAbs for larger than 32 bits", .{});
2986 }
2987
2988 // promote the src into a register
2989 const src_mcv = try self.copyToNewRegister(inst, operand);
2990 // temp register for shift
2991 const temp_reg = try self.register_manager.allocReg(inst, gp);
2992
2993 _ = try self.addInst(.{
2994 .tag = .abs,
2995 .ops = .rri,
2996 .data = .{
2997 .i_type = .{
2998 .rs1 = src_mcv.register,
2999 .rd = temp_reg,
3000 .imm12 = Immediate.s(int_bits - 1),
3001 },
3002 },
3003 });
3004
3005 break :result src_mcv;
3006 },
3007 else => return self.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(zcu)}),
3008 }
3009 };
14453010 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14463011}
14473012
14483013fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
14493014 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1450 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airByteSwap for {}", .{self.target.cpu.arch});
3015 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
3016 const zcu = self.bin_file.comp.module.?;
3017 const ty = self.typeOf(ty_op.operand);
3018 const operand = try self.resolveInst(ty_op.operand);
3019
3020 const int_bits = ty.intInfo(zcu).bits;
3021
3022 // bytes are no-op
3023 if (int_bits == 8 and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
3024 return self.finishAir(inst, operand, .{ ty_op.operand, .none, .none });
3025 }
3026
3027 const dest_reg = try self.register_manager.allocReg(null, gp);
3028 try self.genSetReg(ty, dest_reg, operand);
3029
3030 const dest_mcv: MCValue = .{ .register = dest_reg };
3031
3032 switch (int_bits) {
3033 16 => {
3034 const temp = try self.binOp(.shr, dest_mcv, ty, .{ .immediate = 8 }, Type.u8);
3035 assert(temp == .register);
3036 _ = try self.addInst(.{
3037 .tag = .slli,
3038 .ops = .rri,
3039 .data = .{ .i_type = .{
3040 .imm12 = Immediate.s(8),
3041 .rd = dest_reg,
3042 .rs1 = dest_reg,
3043 } },
3044 });
3045 _ = try self.addInst(.{
3046 .tag = .@"or",
3047 .ops = .rri,
3048 .data = .{ .r_type = .{
3049 .rd = dest_reg,
3050 .rs1 = dest_reg,
3051 .rs2 = temp.register,
3052 } },
3053 });
3054 },
3055 else => return self.fail("TODO: {d} bits for airByteSwap", .{int_bits}),
3056 }
3057
3058 break :result dest_mcv;
3059 };
14513060 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14523061}
14533062
14543063fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
14553064 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1456 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airBitReverse for {}", .{self.target.cpu.arch});
3065 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airBitReverse for {}", .{self.target.cpu.arch});
14573066 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
14583067}
14593068
14603069fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {
14613070 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
14623071 const result: MCValue = if (self.liveness.isUnused(inst))
1463 .dead
3072 .unreach
14643073 else
14653074 return self.fail("TODO implement airUnaryMath for {}", .{self.target.cpu.arch});
14663075 return self.finishAir(inst, result, .{ un_op, .none, .none });
14673076}
14683077
1469fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_index: Liveness.OperandInt, mcv: MCValue) bool {
3078fn reuseOperand(
3079 self: *Self,
3080 inst: Air.Inst.Index,
3081 operand: Air.Inst.Ref,
3082 op_index: Liveness.OperandInt,
3083 mcv: MCValue,
3084) bool {
3085 return self.reuseOperandAdvanced(inst, operand, op_index, mcv, inst);
3086}
3087
3088fn reuseOperandAdvanced(
3089 self: *Self,
3090 inst: Air.Inst.Index,
3091 operand: Air.Inst.Ref,
3092 op_index: Liveness.OperandInt,
3093 mcv: MCValue,
3094 maybe_tracked_inst: ?Air.Inst.Index,
3095) bool {
14703096 if (!self.liveness.operandDies(inst, op_index))
14713097 return false;
14723098
14733099 switch (mcv) {
1474 .register => |reg| {
1475 // If it's in the registers table, need to associate the register with the
3100 .register,
3101 .register_pair,
3102 => for (mcv.getRegs()) |reg| {
3103 // If it's in the registers table, need to associate the register(s) with the
14763104 // new instruction.
1477 if (RegisterManager.indexOfRegIntoTracked(reg)) |index| {
3105 if (maybe_tracked_inst) |tracked_inst| {
14783106 if (!self.register_manager.isRegFree(reg)) {
1479 self.register_manager.registers[index] = inst;
3107 if (RegisterManager.indexOfRegIntoTracked(reg)) |index| {
3108 self.register_manager.registers[index] = tracked_inst;
3109 }
14803110 }
1481 }
1482 log.debug("%{d} => {} (reused)", .{ inst, reg });
1483 },
1484 .stack_offset => |off| {
1485 log.debug("%{d} => stack offset {d} (reused)", .{ inst, off });
3111 } else self.register_manager.freeReg(reg);
14863112 },
3113 .load_frame => |frame_addr| if (frame_addr.index.isNamed()) return false,
14873114 else => return false,
14883115 }
14893116
14903117 // Prevent the operand deaths processing code from deallocating it.
14913118 self.liveness.clearOperandDeath(inst, op_index);
1492
1493 // That makes us responsible for doing the rest of the stuff that processDeath would have done.
1494 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
1495 branch.inst_table.putAssumeCapacity(operand.toIndex().?, .dead);
3119 const op_inst = operand.toIndex().?;
3120 self.getResolvedInstValue(op_inst).reuse(self, maybe_tracked_inst, op_inst);
14963121
14973122 return true;
14983123}
14993124
1500fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
1501 const mod = self.bin_file.comp.module.?;
1502 const elem_ty = ptr_ty.childType(mod);
1503 switch (ptr) {
1504 .none => unreachable,
1505 .undef => unreachable,
1506 .unreach => unreachable,
1507 .dead => unreachable,
1508 .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }),
1509 .ptr_stack_offset => |off| try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }),
1510 .register => {
1511 return self.fail("TODO implement loading from MCValue.register", .{});
1512 },
1513 .memory,
1514 .stack_offset,
1515 => {
1516 const reg = try self.register_manager.allocReg(null, gp);
1517 const reg_lock = self.register_manager.lockRegAssumeUnused(reg);
1518 defer self.register_manager.unlockReg(reg_lock);
1519
1520 try self.genSetReg(ptr_ty, reg, ptr);
1521 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);
1522 },
1523 }
1524}
1525
15263125fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1527 const mod = self.bin_file.comp.module.?;
3126 const zcu = self.bin_file.comp.module.?;
15283127 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
15293128 const elem_ty = self.typeOfIndex(inst);
15303129 const result: MCValue = result: {
1531 if (!elem_ty.hasRuntimeBits(mod))
1532 break :result MCValue.none;
3130 if (!elem_ty.hasRuntimeBits(zcu))
3131 break :result .none;
15333132
15343133 const ptr = try self.resolveInst(ty_op.operand);
1535 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
3134 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(zcu);
15363135 if (self.liveness.isUnused(inst) and !is_volatile)
1537 break :result MCValue.dead;
3136 break :result .unreach;
15383137
15393138 const dst_mcv: MCValue = blk: {
15403139 if (self.reuseOperand(inst, ty_op.operand, 0, ptr)) {
......@@ -1544,35 +3143,47 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
15443143 break :blk try self.allocRegOrMem(inst, true);
15453144 }
15463145 };
3146
15473147 try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
15483148 break :result dst_mcv;
15493149 };
15503150 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
15513151}
15523152
1553fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) !void {
1554 _ = ptr_ty;
3153fn load(self: *Self, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerError!void {
3154 const zcu = self.bin_file.comp.module.?;
3155 const dst_ty = ptr_ty.childType(zcu);
3156
3157 log.debug("loading {}:{} into {}", .{ ptr_mcv, ptr_ty.fmt(zcu), dst_mcv });
3158
3159 switch (ptr_mcv) {
3160 .none,
3161 .undef,
3162 .unreach,
3163 .dead,
3164 .register_pair,
3165 .reserved_frame,
3166 => unreachable, // not a valid pointer
3167
3168 .immediate,
3169 .register,
3170 .register_offset,
3171 .lea_frame,
3172 .lea_symbol,
3173 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()),
15553174
1556 switch (ptr) {
1557 .none => unreachable,
1558 .undef => unreachable,
1559 .unreach => unreachable,
1560 .dead => unreachable,
1561 .immediate => |imm| {
1562 try self.setRegOrMem(value_ty, .{ .memory = imm }, value);
1563 },
1564 .ptr_stack_offset => |off| {
1565 try self.genSetStack(value_ty, off, value);
1566 },
1567 .register => {
1568 return self.fail("TODO implement storing to MCValue.register", .{});
1569 },
1570 .memory => {
1571 return self.fail("TODO implement storing to MCValue.memory", .{});
1572 },
1573 .stack_offset => {
1574 return self.fail("TODO implement storing to MCValue.stack_offset", .{});
3175 .memory,
3176 .indirect,
3177 .load_symbol,
3178 .load_frame,
3179 => {
3180 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
3181 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3182 defer self.register_manager.unlockReg(addr_lock);
3183
3184 try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } });
15753185 },
3186 .air_ref => |ptr_ref| try self.load(dst_mcv, try self.resolveInst(ptr_ref), ptr_ty),
15763187 }
15773188}
15783189
......@@ -1590,33 +3201,186 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
15903201
15913202 try self.store(ptr, value, ptr_ty, value_ty);
15923203
1593 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
3204 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
3205}
3206
3207/// Loads `value` into the "payload" of `pointer`.
3208fn store(self: *Self, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type, src_ty: Type) !void {
3209 const zcu = self.bin_file.comp.module.?;
3210
3211 log.debug("storing {}:{} in {}:{}", .{ src_mcv, src_ty.fmt(zcu), ptr_mcv, ptr_ty.fmt(zcu) });
3212
3213 switch (ptr_mcv) {
3214 .none => unreachable,
3215 .undef => unreachable,
3216 .unreach => unreachable,
3217 .dead => unreachable,
3218 .register_pair => unreachable,
3219 .reserved_frame => unreachable,
3220
3221 .immediate,
3222 .register,
3223 .register_offset,
3224 .lea_symbol,
3225 .lea_frame,
3226 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv),
3227
3228 .memory,
3229 .indirect,
3230 .load_symbol,
3231 .load_frame,
3232 => {
3233 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv);
3234 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3235 defer self.register_manager.unlockReg(addr_lock);
3236
3237 try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv);
3238 },
3239 .air_ref => |ptr_ref| try self.store(try self.resolveInst(ptr_ref), src_mcv, ptr_ty, src_ty),
3240 }
15943241}
15953242
15963243fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {
15973244 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
15983245 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
1599 return self.structFieldPtr(extra.struct_operand, ty_pl.ty, extra.field_index);
3246 const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index);
3247 return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none });
16003248}
16013249
16023250fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
16033251 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1604 return self.structFieldPtr(ty_op.operand, ty_op.ty, index);
3252 const result = try self.structFieldPtr(inst, ty_op.operand, index);
3253 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
16053254}
1606fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void {
1607 _ = operand;
1608 _ = ty;
1609 _ = index;
1610 return self.fail("TODO implement codegen struct_field_ptr", .{});
1611 //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none });
3255
3256fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
3257 const zcu = self.bin_file.comp.module.?;
3258 const ptr_field_ty = self.typeOfIndex(inst);
3259 const ptr_container_ty = self.typeOf(operand);
3260 const ptr_container_ty_info = ptr_container_ty.ptrInfo(zcu);
3261 const container_ty = ptr_container_ty.childType(zcu);
3262
3263 const field_offset: i32 = if (zcu.typeToPackedStruct(container_ty)) |struct_obj|
3264 if (ptr_field_ty.ptrInfo(zcu).packed_offset.host_size == 0)
3265 @divExact(zcu.structPackedFieldBitOffset(struct_obj, index) +
3266 ptr_container_ty_info.packed_offset.bit_offset, 8)
3267 else
3268 0
3269 else
3270 @intCast(container_ty.structFieldOffset(index, zcu));
3271
3272 const src_mcv = try self.resolveInst(operand);
3273 const dst_mcv = if (switch (src_mcv) {
3274 .immediate, .lea_frame => true,
3275 .register, .register_offset => self.reuseOperand(inst, operand, 0, src_mcv),
3276 else => false,
3277 }) src_mcv else try self.copyToNewRegister(inst, src_mcv);
3278 return dst_mcv.offset(field_offset);
16123279}
16133280
16143281fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
3282 const mod = self.bin_file.comp.module.?;
3283
16153284 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
16163285 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
1617 _ = extra;
1618 return self.fail("TODO implement codegen struct_field_val", .{});
1619 //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none });
3286 const operand = extra.struct_operand;
3287 const index = extra.field_index;
3288
3289 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
3290 const zcu = self.bin_file.comp.module.?;
3291 const src_mcv = try self.resolveInst(operand);
3292 const struct_ty = self.typeOf(operand);
3293 const field_ty = struct_ty.structFieldType(index, zcu);
3294 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
3295
3296 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
3297 .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8),
3298 .@"packed" => if (zcu.typeToStruct(struct_ty)) |struct_type|
3299 zcu.structPackedFieldBitOffset(struct_type, index)
3300 else
3301 0,
3302 };
3303
3304 switch (src_mcv) {
3305 .dead, .unreach => unreachable,
3306 .register => |src_reg| {
3307 const src_reg_lock = self.register_manager.lockRegAssumeUnused(src_reg);
3308 defer self.register_manager.unlockReg(src_reg_lock);
3309
3310 const dst_reg = if (field_off == 0)
3311 (try self.copyToNewRegister(inst, src_mcv)).register
3312 else
3313 try self.copyToTmpRegister(Type.usize, .{ .register = src_reg });
3314
3315 const dst_mcv: MCValue = .{ .register = dst_reg };
3316 const dst_lock = self.register_manager.lockReg(dst_reg);
3317 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
3318
3319 if (field_off > 0) {
3320 _ = try self.addInst(.{
3321 .tag = .srli,
3322 .ops = .rri,
3323 .data = .{ .i_type = .{
3324 .imm12 = Immediate.s(@intCast(field_off)),
3325 .rd = dst_reg,
3326 .rs1 = dst_reg,
3327 } },
3328 });
3329
3330 return self.fail("TODO: airStructFieldVal register with field_off > 0", .{});
3331 }
3332
3333 break :result if (field_off == 0) dst_mcv else try self.copyToNewRegister(inst, dst_mcv);
3334 },
3335 .load_frame => {
3336 const field_abi_size: u32 = @intCast(field_ty.abiSize(mod));
3337 if (field_off % 8 == 0) {
3338 const field_byte_off = @divExact(field_off, 8);
3339 const off_mcv = src_mcv.address().offset(@intCast(field_byte_off)).deref();
3340 const field_bit_size = field_ty.bitSize(mod);
3341
3342 if (field_abi_size <= 8) {
3343 const int_ty = try mod.intType(
3344 if (field_ty.isAbiInt(mod)) field_ty.intInfo(mod).signedness else .unsigned,
3345 @intCast(field_bit_size),
3346 );
3347
3348 const dst_reg, const dst_lock = try self.allocReg();
3349 const dst_mcv = MCValue{ .register = dst_reg };
3350 defer self.register_manager.unlockReg(dst_lock);
3351
3352 try self.genCopy(int_ty, dst_mcv, off_mcv);
3353 break :result try self.copyToNewRegister(inst, dst_mcv);
3354 }
3355
3356 const container_abi_size: u32 = @intCast(struct_ty.abiSize(mod));
3357 const dst_mcv = if (field_byte_off + field_abi_size <= container_abi_size and
3358 self.reuseOperand(inst, operand, 0, src_mcv))
3359 off_mcv
3360 else dst: {
3361 const dst_mcv = try self.allocRegOrMem(inst, true);
3362 try self.genCopy(field_ty, dst_mcv, off_mcv);
3363 break :dst dst_mcv;
3364 };
3365 if (field_abi_size * 8 > field_bit_size and dst_mcv.isMemory()) {
3366 const tmp_reg, const tmp_lock = try self.allocReg();
3367 defer self.register_manager.unlockReg(tmp_lock);
3368
3369 const hi_mcv =
3370 dst_mcv.address().offset(@intCast(field_bit_size / 64 * 8)).deref();
3371 try self.genSetReg(Type.usize, tmp_reg, hi_mcv);
3372 try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg });
3373 }
3374 break :result dst_mcv;
3375 }
3376
3377 return self.fail("TODO: airStructFieldVal load_frame field_off non multiple of 8", .{});
3378 },
3379 else => return self.fail("TODO: airStructField {s}", .{@tagName(src_mcv)}),
3380 }
3381 };
3382
3383 return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none });
16203384}
16213385
16223386fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
......@@ -1625,18 +3389,18 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
16253389}
16263390
16273391fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
1628 const mod = self.bin_file.comp.module.?;
3392 const zcu = self.bin_file.comp.module.?;
16293393 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
16303394 const ty = arg.ty.toType();
1631 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
1632 const name = mod.getParamName(self.func_index, arg.src_index);
3395 const owner_decl = zcu.funcOwnerDeclIndex(self.func_index);
3396 const name = zcu.getParamName(self.func_index, arg.src_index);
16333397
16343398 switch (self.debug_output) {
16353399 .dwarf => |dw| switch (mcv) {
16363400 .register => |reg| try dw.genArgDbgInfo(name, ty, owner_decl, .{
16373401 .register = reg.dwarfLocOp(),
16383402 }),
1639 .stack_offset => {},
3403 .load_frame => {},
16403404 else => {},
16413405 },
16423406 .plan9 => {},
......@@ -1645,35 +3409,53 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
16453409}
16463410
16473411fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1648 const arg_index = self.arg_index;
1649 self.arg_index += 1;
1650
1651 const ty = self.typeOfIndex(inst);
1652 _ = ty;
1653
1654 const result = self.args[arg_index];
1655 // TODO support stack-only arguments
1656 // TODO Copy registers to the stack
1657 const mcv = result;
1658 try self.genArgDbgInfo(inst, mcv);
1659
1660 if (self.liveness.isUnused(inst))
1661 return self.finishAirBookkeeping();
3412 const zcu = self.bin_file.comp.module.?;
3413 var arg_index = self.arg_index;
3414
3415 // we skip over args that have no bits
3416 while (self.args[arg_index] == .none) arg_index += 1;
3417 self.arg_index = arg_index + 1;
3418
3419 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
3420 const src_mcv = self.args[arg_index];
3421
3422 const arg_ty = self.typeOfIndex(inst);
3423
3424 const dst_mcv = switch (src_mcv) {
3425 .register => dst: {
3426 const frame = try self.allocFrameIndex(FrameAlloc.init(.{
3427 .size = Type.usize.abiSize(zcu),
3428 .alignment = Type.usize.abiAlignment(zcu),
3429 }));
3430 const dst_mcv: MCValue = .{ .load_frame = .{ .index = frame } };
3431 try self.genCopy(Type.usize, dst_mcv, src_mcv);
3432 break :dst dst_mcv;
3433 },
3434 .register_pair => dst: {
3435 const frame = try self.allocFrameIndex(FrameAlloc.init(.{
3436 .size = Type.usize.abiSize(zcu) * 2,
3437 .alignment = Type.usize.abiAlignment(zcu),
3438 }));
3439 const dst_mcv: MCValue = .{ .load_frame = .{ .index = frame } };
3440 try self.genCopy(arg_ty, dst_mcv, src_mcv);
3441 break :dst dst_mcv;
3442 },
3443 .load_frame => src_mcv,
3444 else => return self.fail("TODO: airArg {s}", .{@tagName(src_mcv)}),
3445 };
16623446
1663 switch (mcv) {
1664 .register => |reg| {
1665 self.register_manager.getRegAssumeFree(reg, inst);
1666 },
1667 else => {},
1668 }
3447 try self.genArgDbgInfo(inst, src_mcv);
3448 break :result dst_mcv;
3449 };
16693450
1670 return self.finishAir(inst, mcv, .{ .none, .none, .none });
3451 return self.finishAir(inst, result, .{ .none, .none, .none });
16713452}
16723453
16733454fn airTrap(self: *Self) !void {
16743455 _ = try self.addInst(.{
16753456 .tag = .unimp,
1676 .data = .{ .nop = {} },
3457 .ops = .none,
3458 .data = undefined,
16773459 });
16783460 return self.finishAirBookkeeping();
16793461}
......@@ -1681,19 +3463,22 @@ fn airTrap(self: *Self) !void {
16813463fn airBreakpoint(self: *Self) !void {
16823464 _ = try self.addInst(.{
16833465 .tag = .ebreak,
1684 .data = .{ .nop = {} },
3466 .ops = .none,
3467 .data = undefined,
16853468 });
16863469 return self.finishAirBookkeeping();
16873470}
16883471
16893472fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
1690 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for riscv64", .{});
1691 return self.finishAir(inst, result, .{ .none, .none, .none });
3473 const dst_mcv = try self.allocRegOrMem(inst, true);
3474 try self.genCopy(Type.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } });
3475 return self.finishAir(inst, dst_mcv, .{ .none, .none, .none });
16923476}
16933477
16943478fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1695 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for riscv64", .{});
1696 return self.finishAir(inst, result, .{ .none, .none, .none });
3479 const dst_mcv = try self.allocRegOrMem(inst, true);
3480 try self.genCopy(Type.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } });
3481 return self.finishAir(inst, dst_mcv, .{ .none, .none, .none });
16973482}
16983483
16993484fn airFence(self: *Self) !void {
......@@ -1702,152 +3487,257 @@ fn airFence(self: *Self) !void {
17023487}
17033488
17043489fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
1705 const mod = self.bin_file.comp.module.?;
17063490 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
17073491 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
1708 const fn_ty = self.typeOf(pl_op.operand);
17093492 const callee = pl_op.operand;
17103493 const extra = self.air.extraData(Air.Call, pl_op.payload);
1711 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
3494 const arg_refs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
3495
3496 const expected_num_args = 8;
3497 const ExpectedContents = extern struct {
3498 vals: [expected_num_args][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
3499 };
3500 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
3501 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
3502 const allocator = stack.get();
3503
3504 const arg_tys = try allocator.alloc(Type, arg_refs.len);
3505 defer allocator.free(arg_tys);
3506 for (arg_tys, arg_refs) |*arg_ty, arg_ref| arg_ty.* = self.typeOf(arg_ref);
3507
3508 const arg_vals = try allocator.alloc(MCValue, arg_refs.len);
3509 defer allocator.free(arg_vals);
3510 for (arg_vals, arg_refs) |*arg_val, arg_ref| arg_val.* = .{ .air_ref = arg_ref };
3511
3512 const call_ret = try self.genCall(.{ .air = callee }, arg_tys, arg_vals);
3513
3514 var bt = self.liveness.iterateBigTomb(inst);
3515 try self.feed(&bt, pl_op.operand);
3516 for (arg_refs) |arg_ref| try self.feed(&bt, arg_ref);
3517
3518 const result = if (self.liveness.isUnused(inst)) .unreach else call_ret;
3519 return self.finishAirResult(inst, result);
3520}
3521
3522fn genCall(
3523 self: *Self,
3524 info: union(enum) {
3525 air: Air.Inst.Ref,
3526 lib: struct {
3527 return_type: InternPool.Index,
3528 param_types: []const InternPool.Index,
3529 lib: ?[]const u8 = null,
3530 callee: []const u8,
3531 },
3532 },
3533 arg_tys: []const Type,
3534 args: []const MCValue,
3535) !MCValue {
3536 const zcu = self.bin_file.comp.module.?;
3537
3538 const fn_ty = switch (info) {
3539 .air => |callee| fn_info: {
3540 const callee_ty = self.typeOf(callee);
3541 break :fn_info switch (callee_ty.zigTypeTag(zcu)) {
3542 .Fn => callee_ty,
3543 .Pointer => callee_ty.childType(zcu),
3544 else => unreachable,
3545 };
3546 },
3547 .lib => |lib| try zcu.funcType(.{
3548 .param_types = lib.param_types,
3549 .return_type = lib.return_type,
3550 .cc = .C,
3551 }),
3552 };
3553
3554 const fn_info = zcu.typeToFunc(fn_ty).?;
3555 var call_info = try self.resolveCallingConventionValues(fn_info);
3556 defer call_info.deinit(self);
3557
3558 // We need a properly aligned and sized call frame to be able to call this function.
3559 {
3560 const needed_call_frame = FrameAlloc.init(.{
3561 .size = call_info.stack_byte_count,
3562 .alignment = call_info.stack_align,
3563 });
3564 const frame_allocs_slice = self.frame_allocs.slice();
3565 const stack_frame_size =
3566 &frame_allocs_slice.items(.abi_size)[@intFromEnum(FrameIndex.call_frame)];
3567 stack_frame_size.* = @max(stack_frame_size.*, needed_call_frame.abi_size);
3568 const stack_frame_align =
3569 &frame_allocs_slice.items(.abi_align)[@intFromEnum(FrameIndex.call_frame)];
3570 stack_frame_align.* = stack_frame_align.max(needed_call_frame.abi_align);
3571 }
17123572
1713 var info = try self.resolveCallingConventionValues(fn_ty);
1714 defer info.deinit(self);
3573 for (call_info.args, 0..) |mc_arg, arg_i| try self.genCopy(arg_tys[arg_i], mc_arg, args[arg_i]);
17153574
17163575 // Due to incremental compilation, how function calls are generated depends
17173576 // on linking.
1718 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1719 for (info.args, 0..) |mc_arg, arg_i| {
1720 const arg = args[arg_i];
1721 const arg_ty = self.typeOf(arg);
1722 const arg_mcv = try self.resolveInst(args[arg_i]);
1723
1724 switch (mc_arg) {
1725 .none => continue,
1726 .undef => unreachable,
1727 .immediate => unreachable,
1728 .unreach => unreachable,
1729 .dead => unreachable,
1730 .memory => unreachable,
1731 .register => |reg| {
1732 try self.register_manager.getReg(reg, null);
1733 try self.genSetReg(arg_ty, reg, arg_mcv);
1734 },
1735 .stack_offset => {
1736 return self.fail("TODO implement calling with parameters in memory", .{});
1737 },
1738 .ptr_stack_offset => {
1739 return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{});
1740 },
3577 switch (info) {
3578 .air => |callee| {
3579 if (try self.air.value(callee, zcu)) |func_value| {
3580 const func_key = zcu.intern_pool.indexToKey(func_value.ip_index);
3581 switch (switch (func_key) {
3582 else => func_key,
3583 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
3584 .decl => |decl| zcu.intern_pool.indexToKey(zcu.declPtr(decl).val.toIntern()),
3585 else => func_key,
3586 } else func_key,
3587 }) {
3588 .func => |func| {
3589 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
3590 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
3591 const sym = elf_file.symbol(sym_index);
3592
3593 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
3594 const got_addr = sym.zigGotAddress(elf_file);
3595 try self.genSetReg(Type.usize, .ra, .{ .memory = @intCast(got_addr) });
3596
3597 _ = try self.addInst(.{
3598 .tag = .jalr,
3599 .ops = .rri,
3600 .data = .{ .i_type = .{
3601 .rd = .ra,
3602 .rs1 = .ra,
3603 .imm12 = Immediate.s(0),
3604 } },
3605 });
3606 } else unreachable;
3607 },
3608 .extern_func => return self.fail("TODO: extern func calls", .{}),
3609 else => return self.fail("TODO implement calling bitcasted functions", .{}),
3610 }
3611 } else {
3612 assert(self.typeOf(callee).zigTypeTag(zcu) == .Pointer);
3613 const addr_reg, const addr_lock = try self.allocReg();
3614 defer self.register_manager.unlockReg(addr_lock);
3615 try self.genSetReg(Type.usize, addr_reg, .{ .air_ref = callee });
3616 _ = try self.addInst(.{
3617 .tag = .jalr,
3618 .ops = .rri,
3619 .data = .{ .i_type = .{
3620 .rd = .ra,
3621 .rs1 = addr_reg,
3622 .imm12 = Immediate.s(0),
3623 } },
3624 });
17413625 }
1742 }
3626 },
3627 .lib => return self.fail("TODO: lib func calls", .{}),
3628 }
17433629
1744 if (try self.air.value(callee, mod)) |func_value| {
1745 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
1746 .func => |func| {
1747 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1748 const sym = elf_file.symbol(sym_index);
1749 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
1750 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
1751 try self.genSetReg(Type.usize, .ra, .{ .memory = got_addr });
1752 _ = try self.addInst(.{
1753 .tag = .jalr,
1754 .data = .{ .i_type = .{
1755 .rd = .ra,
1756 .rs1 = .ra,
1757 .imm12 = 0,
1758 } },
1759 });
1760 },
1761 .extern_func => {
1762 return self.fail("TODO implement calling extern functions", .{});
1763 },
1764 else => {
1765 return self.fail("TODO implement calling bitcasted functions", .{});
1766 },
1767 }
1768 } else {
1769 return self.fail("TODO implement calling runtime-known function pointer", .{});
1770 }
1771 } else if (self.bin_file.cast(link.File.Coff)) |_| {
1772 return self.fail("TODO implement calling in COFF for {}", .{self.target.cpu.arch});
1773 } else if (self.bin_file.cast(link.File.MachO)) |_| {
1774 unreachable; // unsupported architecture for MachO
1775 } else if (self.bin_file.cast(link.File.Plan9)) |_| {
1776 return self.fail("TODO implement call on plan9 for {}", .{self.target.cpu.arch});
1777 } else unreachable;
3630 return call_info.return_value.short;
3631}
17783632
1779 const result: MCValue = result: {
1780 switch (info.return_value) {
1781 .register => |reg| {
1782 if (RegisterManager.indexOfReg(&callee_preserved_regs, reg) == null) {
1783 // Save function return value in a callee saved register
1784 break :result try self.copyToNewRegister(inst, info.return_value);
1785 }
1786 },
1787 else => {},
1788 }
1789 break :result info.return_value;
1790 };
3633fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
3634 const zcu = self.bin_file.comp.module.?;
3635 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
17913636
1792 if (args.len <= Liveness.bpi - 2) {
1793 var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1);
1794 buf[0] = callee;
1795 @memcpy(buf[1..][0..args.len], args);
1796 return self.finishAir(inst, result, buf);
3637 if (safety) {
3638 // safe
3639 } else {
3640 // not safe
17973641 }
1798 var bt = try self.iterateBigTomb(inst, 1 + args.len);
1799 bt.feed(callee);
1800 for (args) |arg| {
1801 bt.feed(arg);
3642
3643 const ret_ty = self.fn_type.fnReturnType(zcu);
3644 switch (self.ret_mcv.short) {
3645 .none => {},
3646 .register,
3647 .register_pair,
3648 => try self.genCopy(ret_ty, self.ret_mcv.short, .{ .air_ref = un_op }),
3649 .indirect => |reg_off| {
3650 try self.register_manager.getReg(reg_off.reg, null);
3651 const lock = self.register_manager.lockRegAssumeUnused(reg_off.reg);
3652 defer self.register_manager.unlockReg(lock);
3653
3654 try self.genSetReg(Type.usize, reg_off.reg, self.ret_mcv.long);
3655 try self.genCopy(
3656 ret_ty,
3657 .{ .register_offset = reg_off },
3658 .{ .air_ref = un_op },
3659 );
3660 },
3661 else => unreachable,
18023662 }
1803 return bt.finishAir(result);
1804}
18053663
1806fn ret(self: *Self, mcv: MCValue) !void {
1807 const mod = self.bin_file.comp.module.?;
1808 const ret_ty = self.fn_type.fnReturnType(mod);
1809 try self.setRegOrMem(ret_ty, self.ret_mcv, mcv);
1810 // Just add space for an instruction, patch this later
3664 self.ret_mcv.liveOut(self, inst);
3665 try self.finishAir(inst, .unreach, .{ un_op, .none, .none });
3666
3667 // Just add space for an instruction, reloced this later
18113668 const index = try self.addInst(.{
1812 .tag = .nop,
1813 .data = .{ .nop = {} },
3669 .tag = .pseudo,
3670 .ops = .pseudo_j,
3671 .data = .{ .inst = undefined },
18143672 });
1815 try self.exitlude_jump_relocs.append(self.gpa, index);
1816}
18173673
1818fn airRet(self: *Self, inst: Air.Inst.Index) !void {
1819 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1820 const operand = try self.resolveInst(un_op);
1821 try self.ret(operand);
1822 return self.finishAir(inst, .dead, .{ un_op, .none, .none });
3674 try self.exitlude_jump_relocs.append(self.gpa, index);
18233675}
18243676
18253677fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
18263678 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
18273679 const ptr = try self.resolveInst(un_op);
1828 _ = ptr;
1829 return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch});
1830 //return self.finishAir(inst, .dead, .{ un_op, .none, .none });
3680
3681 const ptr_ty = self.typeOf(un_op);
3682 switch (self.ret_mcv.short) {
3683 .none => {},
3684 .register, .register_pair => try self.load(self.ret_mcv.short, ptr, ptr_ty),
3685 .indirect => |reg_off| try self.genSetReg(ptr_ty, reg_off.reg, ptr),
3686 else => unreachable,
3687 }
3688 self.ret_mcv.liveOut(self, inst);
3689 try self.finishAir(inst, .unreach, .{ un_op, .none, .none });
3690
3691 // Just add space for an instruction, reloced this later
3692 const index = try self.addInst(.{
3693 .tag = .pseudo,
3694 .ops = .pseudo_j,
3695 .data = .{ .inst = undefined },
3696 });
3697
3698 try self.exitlude_jump_relocs.append(self.gpa, index);
18313699}
18323700
1833fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
3701fn airCmp(self: *Self, inst: Air.Inst.Index) !void {
3702 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
18343703 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1835 if (self.liveness.isUnused(inst))
1836 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1837 const ty = self.typeOf(bin_op.lhs);
1838 const mod = self.bin_file.comp.module.?;
1839 assert(ty.eql(self.typeOf(bin_op.rhs), mod));
1840 if (ty.zigTypeTag(mod) == .ErrorSet)
1841 return self.fail("TODO implement cmp for errors", .{});
3704 const zcu = self.bin_file.comp.module.?;
3705
3706 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
3707 const lhs = try self.resolveInst(bin_op.lhs);
3708 const rhs = try self.resolveInst(bin_op.rhs);
3709 const lhs_ty = self.typeOf(bin_op.lhs);
3710
3711 const int_ty = switch (lhs_ty.zigTypeTag(zcu)) {
3712 .Vector => unreachable, // Handled by cmp_vector.
3713 .Enum => lhs_ty.intTagType(zcu),
3714 .Int => lhs_ty,
3715 .Bool => Type.u1,
3716 .Pointer => Type.usize,
3717 .ErrorSet => Type.u16,
3718 .Optional => blk: {
3719 const payload_ty = lhs_ty.optionalChild(zcu);
3720 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3721 break :blk Type.u1;
3722 } else if (lhs_ty.isPtrLikeOptional(zcu)) {
3723 break :blk Type.usize;
3724 } else {
3725 return self.fail("TODO riscv cmp non-pointer optionals", .{});
3726 }
3727 },
3728 .Float => return self.fail("TODO riscv cmp floats", .{}),
3729 else => unreachable,
3730 };
18423731
1843 const lhs = try self.resolveInst(bin_op.lhs);
1844 const rhs = try self.resolveInst(bin_op.rhs);
1845 _ = op;
1846 _ = lhs;
1847 _ = rhs;
3732 const int_info = int_ty.intInfo(zcu);
3733 if (int_info.bits <= 64) {
3734 break :result try self.binOp(tag, lhs, int_ty, rhs, int_ty);
3735 } else {
3736 return self.fail("TODO riscv cmp for ints > 64 bits", .{});
3737 }
3738 };
18483739
1849 return self.fail("TODO implement cmp for {}", .{self.target.cpu.arch});
1850 // return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
3740 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
18513741}
18523742
18533743fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
......@@ -1859,7 +3749,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
18593749 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
18603750 const operand = try self.resolveInst(un_op);
18613751 _ = operand;
1862 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch});
3752 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch});
18633753 return self.finishAir(inst, result, .{ un_op, .none, .none });
18643754}
18653755
......@@ -1867,8 +3757,9 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
18673757 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
18683758
18693759 _ = try self.addInst(.{
1870 .tag = .dbg_line,
1871 .data = .{ .dbg_line_column = .{
3760 .tag = .pseudo,
3761 .ops = .pseudo_dbg_line_column,
3762 .data = .{ .pseudo_dbg_line_column = .{
18723763 .line = dbg_stmt.line,
18733764 .column = dbg_stmt.column,
18743765 } },
......@@ -1878,62 +3769,126 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
18783769}
18793770
18803771fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
1881 const mod = self.bin_file.comp.module.?;
18823772 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
18833773 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
1884 const func = mod.funcInfo(extra.data.func);
1885 // TODO emit debug info for function change
1886 _ = func;
18873774 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
18883775}
18893776
18903777fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
18913778 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
1892 const name = self.air.nullTerminatedString(pl_op.payload);
18933779 const operand = pl_op.operand;
1894 // TODO emit debug info for this variable
1895 _ = name;
1896 return self.finishAir(inst, .dead, .{ operand, .none, .none });
1897}
3780 const ty = self.typeOf(operand);
3781 const mcv = try self.resolveInst(operand);
18983782
1899fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
1900 _ = inst;
3783 const name = self.air.nullTerminatedString(pl_op.payload);
19013784
1902 return self.fail("TODO implement condbr {}", .{self.target.cpu.arch});
1903 // return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
1904}
3785 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
3786 try self.genVarDbgInfo(tag, ty, mcv, name);
19053787
1906fn isNull(self: *Self, operand: MCValue) !MCValue {
1907 _ = operand;
1908 // Here you can specialize this instruction if it makes sense to, otherwise the default
1909 // will call isNonNull and invert the result.
1910 return self.fail("TODO call isNonNull and invert the result", .{});
3788 return self.finishAir(inst, .unreach, .{ operand, .none, .none });
19113789}
19123790
1913fn isNonNull(self: *Self, operand: MCValue) !MCValue {
1914 _ = operand;
1915 // Here you can specialize this instruction if it makes sense to, otherwise the default
1916 // will call isNull and invert the result.
1917 return self.fail("TODO call isNull and invert the result", .{});
3791fn genVarDbgInfo(
3792 self: Self,
3793 tag: Air.Inst.Tag,
3794 ty: Type,
3795 mcv: MCValue,
3796 name: [:0]const u8,
3797) !void {
3798 const zcu = self.bin_file.comp.module.?;
3799 const is_ptr = switch (tag) {
3800 .dbg_var_ptr => true,
3801 .dbg_var_val => false,
3802 else => unreachable,
3803 };
3804
3805 switch (self.debug_output) {
3806 .dwarf => |dw| {
3807 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
3808 .register => |reg| .{ .register = reg.dwarfLocOp() },
3809 .memory => |address| .{ .memory = address },
3810 .load_symbol => |sym_off| loc: {
3811 assert(sym_off.off == 0);
3812 break :loc .{ .linker_load = .{ .type = .direct, .sym_index = sym_off.sym } };
3813 },
3814 .immediate => |x| .{ .immediate = x },
3815 .undef => .undef,
3816 .none => .none,
3817 else => blk: {
3818 // log.warn("TODO generate debug info for {}", .{mcv});
3819 break :blk .nop;
3820 },
3821 };
3822 try dw.genVarDbgInfo(name, ty, zcu.funcOwnerDeclIndex(self.func_index), is_ptr, loc);
3823 },
3824 .plan9 => {},
3825 .none => {},
3826 }
19183827}
19193828
1920fn isErr(self: *Self, operand: MCValue) !MCValue {
1921 _ = operand;
1922 // Here you can specialize this instruction if it makes sense to, otherwise the default
1923 // will call isNonNull and invert the result.
1924 return self.fail("TODO call isNonErr and invert the result", .{});
3829fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
3830 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
3831 const cond = try self.resolveInst(pl_op.operand);
3832 const cond_ty = self.typeOf(pl_op.operand);
3833 const extra = self.air.extraData(Air.CondBr, pl_op.payload);
3834 const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.then_body_len]);
3835 const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
3836 const liveness_cond_br = self.liveness.getCondBr(inst);
3837
3838 // If the condition dies here in this condbr instruction, process
3839 // that death now instead of later as this has an effect on
3840 // whether it needs to be spilled in the branches
3841 if (self.liveness.operandDies(inst, 0)) {
3842 if (pl_op.operand.toIndex()) |op_inst| try self.processDeath(op_inst);
3843 }
3844
3845 self.scope_generation += 1;
3846 const state = try self.saveState();
3847 const reloc = try self.condBr(cond_ty, cond);
3848
3849 for (liveness_cond_br.then_deaths) |death| try self.processDeath(death);
3850 try self.genBody(then_body);
3851 try self.restoreState(state, &.{}, .{
3852 .emit_instructions = false,
3853 .update_tracking = true,
3854 .resurrect = true,
3855 .close_scope = true,
3856 });
3857
3858 self.performReloc(reloc);
3859
3860 for (liveness_cond_br.else_deaths) |death| try self.processDeath(death);
3861 try self.genBody(else_body);
3862 try self.restoreState(state, &.{}, .{
3863 .emit_instructions = false,
3864 .update_tracking = true,
3865 .resurrect = true,
3866 .close_scope = true,
3867 });
3868
3869 // We already took care of pl_op.operand earlier, so there's nothing left to do.
3870 self.finishAirBookkeeping();
19253871}
19263872
1927fn isNonErr(self: *Self, operand: MCValue) !MCValue {
1928 _ = operand;
1929 // Here you can specialize this instruction if it makes sense to, otherwise the default
1930 // will call isNull and invert the result.
1931 return self.fail("TODO call isErr and invert the result", .{});
3873fn condBr(self: *Self, cond_ty: Type, condition: MCValue) !Mir.Inst.Index {
3874 const cond_reg = try self.copyToTmpRegister(cond_ty, condition);
3875
3876 return try self.addInst(.{
3877 .tag = .beq,
3878 .ops = .rr_inst,
3879 .data = .{
3880 .b_type = .{
3881 .rs1 = cond_reg,
3882 .rs2 = .zero,
3883 .inst = undefined,
3884 },
3885 },
3886 });
19323887}
19333888
19343889fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
19353890 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1936 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3891 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
19373892 const operand = try self.resolveInst(un_op);
19383893 break :result try self.isNull(operand);
19393894 };
......@@ -1942,7 +3897,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
19423897
19433898fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
19443899 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1945 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3900 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
19463901 const operand_ptr = try self.resolveInst(un_op);
19473902 const operand: MCValue = blk: {
19483903 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {
......@@ -1958,18 +3913,32 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
19583913 return self.finishAir(inst, result, .{ un_op, .none, .none });
19593914}
19603915
3916fn isNull(self: *Self, operand: MCValue) !MCValue {
3917 _ = operand;
3918 // Here you can specialize this instruction if it makes sense to, otherwise the default
3919 // will call isNonNull and invert the result.
3920 return self.fail("TODO call isNonNull and invert the result", .{});
3921}
3922
19613923fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
19623924 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1963 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3925 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
19643926 const operand = try self.resolveInst(un_op);
19653927 break :result try self.isNonNull(operand);
19663928 };
19673929 return self.finishAir(inst, result, .{ un_op, .none, .none });
19683930}
19693931
3932fn isNonNull(self: *Self, operand: MCValue) !MCValue {
3933 _ = operand;
3934 // Here you can specialize this instruction if it makes sense to, otherwise the default
3935 // will call isNull and invert the result.
3936 return self.fail("TODO call isNull and invert the result", .{});
3937}
3938
19703939fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
19713940 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1972 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3941 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
19733942 const operand_ptr = try self.resolveInst(un_op);
19743943 const operand: MCValue = blk: {
19753944 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {
......@@ -1987,16 +3956,18 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
19873956
19883957fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
19893958 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1990 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3959 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
19913960 const operand = try self.resolveInst(un_op);
1992 break :result try self.isErr(operand);
3961 const operand_ty = self.typeOf(un_op);
3962 break :result try self.isErr(inst, operand_ty, operand);
19933963 };
19943964 return self.finishAir(inst, result, .{ un_op, .none, .none });
19953965}
19963966
19973967fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3968 const zcu = self.bin_file.comp.module.?;
19983969 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1999 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3970 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
20003971 const operand_ptr = try self.resolveInst(un_op);
20013972 const operand: MCValue = blk: {
20023973 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {
......@@ -2007,23 +3978,100 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
20073978 }
20083979 };
20093980 try self.load(operand, operand_ptr, self.typeOf(un_op));
2010 break :result try self.isErr(operand);
3981 const operand_ptr_ty = self.typeOf(un_op);
3982 const operand_ty = operand_ptr_ty.childType(zcu);
3983
3984 break :result try self.isErr(inst, operand_ty, operand);
20113985 };
20123986 return self.finishAir(inst, result, .{ un_op, .none, .none });
20133987}
20143988
3989/// Generates a compare instruction which will indicate if `eu_mcv` is an error.
3990///
3991/// Result is in the return register.
3992fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {
3993 const zcu = self.bin_file.comp.module.?;
3994 const err_ty = eu_ty.errorUnionSet(zcu);
3995 if (err_ty.errorSetIsEmpty(zcu)) return MCValue{ .immediate = 0 }; // always false
3996
3997 _ = maybe_inst;
3998
3999 const err_off = errUnionErrorOffset(eu_ty.errorUnionPayload(zcu), zcu);
4000
4001 switch (eu_mcv) {
4002 .register => |reg| {
4003 const eu_lock = self.register_manager.lockReg(reg);
4004 defer if (eu_lock) |lock| self.register_manager.unlockReg(lock);
4005
4006 const return_reg = try self.copyToTmpRegister(eu_ty, eu_mcv);
4007 const return_lock = self.register_manager.lockRegAssumeUnused(return_reg);
4008 defer self.register_manager.unlockReg(return_lock);
4009
4010 var return_mcv: MCValue = .{ .register = return_reg };
4011
4012 if (err_off > 0) {
4013 return_mcv = try self.binOp(
4014 .shr,
4015 return_mcv,
4016 eu_ty,
4017 .{ .immediate = @as(u6, @intCast(err_off * 8)) },
4018 Type.u8,
4019 );
4020 }
4021
4022 return_mcv = try self.binOp(
4023 .cmp_neq,
4024 return_mcv,
4025 Type.u16,
4026 .{ .immediate = 0 },
4027 Type.u16,
4028 );
4029
4030 return return_mcv;
4031 },
4032 else => return self.fail("TODO implement isErr for {}", .{eu_mcv}),
4033 }
4034}
4035
20154036fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
20164037 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2017 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4038 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
20184039 const operand = try self.resolveInst(un_op);
2019 break :result try self.isNonErr(operand);
4040 const ty = self.typeOf(un_op);
4041 break :result try self.isNonErr(inst, ty, operand);
20204042 };
20214043 return self.finishAir(inst, result, .{ un_op, .none, .none });
20224044}
20234045
4046fn isNonErr(self: *Self, inst: Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {
4047 const is_err_res = try self.isErr(inst, eu_ty, eu_mcv);
4048 switch (is_err_res) {
4049 .register => |reg| {
4050 _ = try self.addInst(.{
4051 .tag = .pseudo,
4052 .ops = .pseudo_not,
4053 .data = .{
4054 .rr = .{
4055 .rd = reg,
4056 .rs = reg,
4057 },
4058 },
4059 });
4060 return is_err_res;
4061 },
4062 // always false case
4063 .immediate => |imm| {
4064 assert(imm == 0);
4065 return MCValue{ .immediate = @intFromBool(imm == 0) };
4066 },
4067 else => unreachable,
4068 }
4069}
4070
20244071fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4072 const zcu = self.bin_file.comp.module.?;
20254073 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2026 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4074 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
20274075 const operand_ptr = try self.resolveInst(un_op);
20284076 const operand: MCValue = blk: {
20294077 if (self.reuseOperand(inst, un_op, 0, operand_ptr)) {
......@@ -2033,8 +4081,11 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
20334081 break :blk try self.allocRegOrMem(inst, true);
20344082 }
20354083 };
4084 const operand_ptr_ty = self.typeOf(un_op);
4085 const operand_ty = operand_ptr_ty.childType(zcu);
4086
20364087 try self.load(operand, operand_ptr, self.typeOf(un_op));
2037 break :result try self.isNonErr(operand);
4088 break :result try self.isNonErr(inst, operand_ty, operand);
20384089 };
20394090 return self.finishAir(inst, result, .{ un_op, .none, .none });
20404091}
......@@ -2044,16 +4095,32 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
20444095 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
20454096 const loop = self.air.extraData(Air.Block, ty_pl.payload);
20464097 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
2047 const start_index = self.code.items.len;
4098
4099 self.scope_generation += 1;
4100 const state = try self.saveState();
4101
4102 const jmp_target: Mir.Inst.Index = @intCast(self.mir_instructions.len);
20484103 try self.genBody(body);
2049 try self.jump(start_index);
2050 return self.finishAirBookkeeping();
4104 try self.restoreState(state, &.{}, .{
4105 .emit_instructions = true,
4106 .update_tracking = false,
4107 .resurrect = false,
4108 .close_scope = true,
4109 });
4110 _ = try self.jump(jmp_target);
4111
4112 self.finishAirBookkeeping();
20514113}
20524114
20534115/// Send control flow to the `index` of `self.code`.
2054fn jump(self: *Self, index: usize) !void {
2055 _ = index;
2056 return self.fail("TODO implement jump for {}", .{self.target.cpu.arch});
4116fn jump(self: *Self, index: Mir.Inst.Index) !Mir.Inst.Index {
4117 return self.addInst(.{
4118 .tag = .pseudo,
4119 .ops = .pseudo_j,
4120 .data = .{
4121 .inst = index,
4122 },
4123 });
20574124}
20584125
20594126fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
......@@ -2063,24 +4130,34 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
20634130}
20644131
20654132fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
2066 try self.blocks.putNoClobber(self.gpa, inst, .{
2067 // A block is a setup to be able to jump to the end.
2068 .relocs = .{},
2069 // It also acts as a receptacle for break operands.
2070 // Here we use `MCValue.none` to represent a null value so that the first
2071 // break instruction will choose a MCValue for the block result and overwrite
2072 // this field. Following break instructions will use that MCValue to put their
2073 // block results.
2074 .mcv = MCValue{ .none = {} },
2075 });
2076 defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
4133 // A block is a setup to be able to jump to the end.
4134 const inst_tracking_i = self.inst_tracking.count();
4135 self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(.unreach));
4136
4137 self.scope_generation += 1;
4138 try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() });
4139 const liveness = self.liveness.getBlock(inst);
4140
20774141 // TODO emit debug info lexical block
20784142 try self.genBody(body);
20794143
2080 for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc);
4144 var block_data = self.blocks.fetchRemove(inst).?;
4145 defer block_data.value.deinit(self.gpa);
4146 if (block_data.value.relocs.items.len > 0) {
4147 try self.restoreState(block_data.value.state, liveness.deaths, .{
4148 .emit_instructions = false,
4149 .update_tracking = true,
4150 .resurrect = true,
4151 .close_scope = true,
4152 });
4153 for (block_data.value.relocs.items) |reloc| self.performReloc(reloc);
4154 }
20814155
2082 const result = self.blocks.getPtr(inst).?.mcv;
2083 return self.finishAir(inst, result, .{ .none, .none, .none });
4156 if (std.debug.runtime_safety) assert(self.inst_tracking.getIndex(inst).? == inst_tracking_i);
4157 const tracking = &self.inst_tracking.values()[inst_tracking_i];
4158 if (self.liveness.isUnused(inst)) try tracking.die(self, inst);
4159 self.getValueIfFree(tracking.short, inst);
4160 self.finishAirBookkeeping();
20844161}
20854162
20864163fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
......@@ -2091,51 +4168,91 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
20914168 // return self.finishAir(inst, .dead, .{ condition, .none, .none });
20924169}
20934170
2094fn performReloc(self: *Self, reloc: Reloc) !void {
2095 _ = self;
2096 switch (reloc) {
2097 .rel32 => unreachable,
2098 .arm_branch => unreachable,
4171fn performReloc(self: *Self, inst: Mir.Inst.Index) void {
4172 const tag = self.mir_instructions.items(.tag)[inst];
4173 const ops = self.mir_instructions.items(.ops)[inst];
4174 const target: Mir.Inst.Index = @intCast(self.mir_instructions.len);
4175
4176 switch (tag) {
4177 .bne,
4178 .beq,
4179 => self.mir_instructions.items(.data)[inst].b_type.inst = target,
4180 .jal => self.mir_instructions.items(.data)[inst].j_type.inst = target,
4181 .pseudo => switch (ops) {
4182 .pseudo_j => self.mir_instructions.items(.data)[inst].inst = target,
4183 else => std.debug.panic("TODO: performReloc {s}", .{@tagName(ops)}),
4184 },
4185 else => std.debug.panic("TODO: performReloc {s}", .{@tagName(tag)}),
20994186 }
21004187}
21014188
21024189fn airBr(self: *Self, inst: Air.Inst.Index) !void {
2103 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
2104 try self.br(branch.block_inst, branch.operand);
2105 return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
2106}
2107
2108fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
2109 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
2110 const air_tags = self.air.instructions.items(.tag);
2111 _ = air_tags;
2112 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement boolean operations for {}", .{self.target.cpu.arch});
2113 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
2114}
2115
2116fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
2117 const block_data = self.blocks.getPtr(block).?;
2118
21194190 const mod = self.bin_file.comp.module.?;
2120 if (self.typeOf(operand).hasRuntimeBits(mod)) {
2121 const operand_mcv = try self.resolveInst(operand);
2122 const block_mcv = block_data.mcv;
2123 if (block_mcv == .none) {
2124 block_data.mcv = operand_mcv;
2125 } else {
2126 try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
4191 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
4192
4193 const block_ty = self.typeOfIndex(br.block_inst);
4194 const block_unused =
4195 !block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst);
4196 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
4197 const block_data = self.blocks.getPtr(br.block_inst).?;
4198 const first_br = block_data.relocs.items.len == 0;
4199 const block_result = result: {
4200 if (block_unused) break :result .none;
4201
4202 if (!first_br) try self.getValue(block_tracking.short, null);
4203 const src_mcv = try self.resolveInst(br.operand);
4204
4205 if (self.reuseOperandAdvanced(inst, br.operand, 0, src_mcv, br.block_inst)) {
4206 if (first_br) break :result src_mcv;
4207
4208 try self.getValue(block_tracking.short, br.block_inst);
4209 // .long = .none to avoid merging operand and block result stack frames.
4210 const current_tracking: InstTracking = .{ .long = .none, .short = src_mcv };
4211 try current_tracking.materializeUnsafe(self, br.block_inst, block_tracking.*);
4212 for (current_tracking.getRegs()) |src_reg| self.register_manager.freeReg(src_reg);
4213 break :result block_tracking.short;
21274214 }
4215
4216 const dst_mcv = if (first_br) try self.allocRegOrMem(br.block_inst, true) else dst: {
4217 try self.getValue(block_tracking.short, br.block_inst);
4218 break :dst block_tracking.short;
4219 };
4220 try self.genCopy(block_ty, dst_mcv, try self.resolveInst(br.operand));
4221 break :result dst_mcv;
4222 };
4223
4224 // Process operand death so that it is properly accounted for in the State below.
4225 if (self.liveness.operandDies(inst, 0)) {
4226 if (br.operand.toIndex()) |op_inst| try self.processDeath(op_inst);
21284227 }
2129 return self.brVoid(block);
2130}
21314228
2132fn brVoid(self: *Self, block: Air.Inst.Index) !void {
2133 const block_data = self.blocks.getPtr(block).?;
4229 if (first_br) {
4230 block_tracking.* = InstTracking.init(block_result);
4231 try self.saveRetroactiveState(&block_data.state);
4232 } else try self.restoreState(block_data.state, &.{}, .{
4233 .emit_instructions = true,
4234 .update_tracking = false,
4235 .resurrect = false,
4236 .close_scope = false,
4237 });
21344238
21354239 // Emit a jump with a relocation. It will be patched up after the block ends.
2136 try block_data.relocs.ensureUnusedCapacity(self.gpa, 1);
4240 // Leave the jump offset undefined
4241 const jmp_reloc = try self.jump(undefined);
4242 try block_data.relocs.append(self.gpa, jmp_reloc);
4243
4244 // Stop tracking block result without forgetting tracking info
4245 try self.freeValue(block_tracking.short);
4246
4247 self.finishAirBookkeeping();
4248}
21374249
2138 return self.fail("TODO implement brvoid for {}", .{self.target.cpu.arch});
4250fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
4251 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4252 const air_tags = self.air.instructions.items(.tag);
4253 _ = air_tags;
4254 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement boolean operations for {}", .{self.target.cpu.arch});
4255 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
21394256}
21404257
21414258fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
......@@ -2144,13 +4261,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
21444261 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
21454262 const clobbers_len: u31 = @truncate(extra.data.flags);
21464263 var extra_i: usize = extra.end;
2147 const outputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]);
4264 const outputs: []const Air.Inst.Ref =
4265 @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]);
21484266 extra_i += outputs.len;
21494267 const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]);
21504268 extra_i += inputs.len;
21514269
4270 log.debug("airAsm input: {any}", .{inputs});
4271
21524272 const dead = !is_volatile and self.liveness.isUnused(inst);
2153 const result: MCValue = if (dead) .dead else result: {
4273 const result: MCValue = if (dead) .unreach else result: {
21544274 if (outputs.len > 1) {
21554275 return self.fail("TODO implement codegen for asm with more than 1 output", .{});
21564276 }
......@@ -2197,19 +4317,25 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
21974317 // for the string, we still use the next u32 for the null terminator.
21984318 extra_i += clobber.len / 4 + 1;
21994319
2200 // TODO honor these
4320 if (std.mem.eql(u8, clobber, "") or std.mem.eql(u8, clobber, "memory")) {
4321 // nothing really to do
4322 } else {
4323 try self.register_manager.getReg(parseRegName(clobber) orelse
4324 return self.fail("invalid clobber: '{s}'", .{clobber}), null);
4325 }
22014326 }
22024327 }
22034328
22044329 const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len];
22054330
2206 if (mem.eql(u8, asm_source, "ecall")) {
4331 if (std.meta.stringToEnum(Mir.Inst.Tag, asm_source)) |tag| {
22074332 _ = try self.addInst(.{
2208 .tag = .ecall,
2209 .data = .{ .nop = {} },
4333 .tag = tag,
4334 .ops = .none,
4335 .data = undefined,
22104336 });
22114337 } else {
2212 return self.fail("TODO implement support for more riscv64 assembly instructions", .{});
4338 return self.fail("TODO: asm_source {s}", .{asm_source});
22134339 }
22144340
22154341 if (output_constraint) |output| {
......@@ -2219,11 +4345,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
22194345 const reg_name = output[2 .. output.len - 1];
22204346 const reg = parseRegName(reg_name) orelse
22214347 return self.fail("unrecognized register: '{s}'", .{reg_name});
2222 break :result MCValue{ .register = reg };
4348 break :result .{ .register = reg };
22234349 } else {
2224 break :result MCValue{ .none = {} };
4350 break :result .{ .none = {} };
22254351 }
22264352 };
4353
22274354 simple: {
22284355 var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1);
22294356 var buf_index: usize = 0;
......@@ -2238,51 +4365,292 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
22384365 @memcpy(buf[buf_index..][0..inputs.len], inputs);
22394366 return self.finishAir(inst, result, buf);
22404367 }
2241 var bt = try self.iterateBigTomb(inst, outputs.len + inputs.len);
2242 for (outputs) |output| {
2243 if (output == .none) continue;
4368 var bt = self.liveness.iterateBigTomb(inst);
4369 for (outputs) |output| if (output != .none) try self.feed(&bt, output);
4370 for (inputs) |input| try self.feed(&bt, input);
4371 return self.finishAirResult(inst, result);
4372}
22444373
2245 bt.feed(output);
2246 }
2247 for (inputs) |input| {
2248 bt.feed(input);
4374/// Sets the value without any modifications to register allocation metadata or stack allocation metadata.
4375fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
4376 const zcu = self.bin_file.comp.module.?;
4377
4378 // There isn't anything to store
4379 if (dst_mcv == .none) return;
4380
4381 if (!dst_mcv.isMutable()) {
4382 // panic so we can see the trace
4383 return self.fail("tried to genCopy immutable: {s}", .{@tagName(dst_mcv)});
22494384 }
2250 return bt.finishAir(result);
2251}
22524385
2253fn iterateBigTomb(self: *Self, inst: Air.Inst.Index, operand_count: usize) !BigTomb {
2254 try self.ensureProcessDeathCapacity(operand_count + 1);
2255 return BigTomb{
2256 .function = self,
2257 .inst = inst,
2258 .lbt = self.liveness.iterateBigTomb(inst),
2259 };
4386 switch (dst_mcv) {
4387 .register => |reg| return self.genSetReg(ty, reg, src_mcv),
4388 .register_offset => |dst_reg_off| try self.genSetReg(ty, dst_reg_off.reg, switch (src_mcv) {
4389 .none,
4390 .unreach,
4391 .dead,
4392 .undef,
4393 => unreachable,
4394 .immediate,
4395 .register,
4396 .register_offset,
4397 => src_mcv.offset(-dst_reg_off.off),
4398 else => .{ .register_offset = .{
4399 .reg = try self.copyToTmpRegister(ty, src_mcv),
4400 .off = -dst_reg_off.off,
4401 } },
4402 }),
4403 .indirect => |ro| {
4404 const src_reg = try self.copyToTmpRegister(ty, src_mcv);
4405
4406 _ = try self.addInst(.{
4407 .tag = .pseudo,
4408 .ops = .pseudo_store_rm,
4409 .data = .{ .rm = .{
4410 .r = src_reg,
4411 .m = .{
4412 .base = .{ .reg = ro.reg },
4413 .mod = .{ .rm = .{ .disp = ro.off, .size = self.memSize(ty) } },
4414 },
4415 } },
4416 });
4417 },
4418 .load_frame => |frame| return self.genSetStack(ty, frame, src_mcv),
4419 .memory => return self.fail("TODO: genCopy memory", .{}),
4420 .register_pair => |dst_regs| {
4421 const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) {
4422 .register_pair, .memory, .indirect, .load_frame => null,
4423 .load_symbol => src: {
4424 const src_addr_reg, const src_addr_lock = try self.allocReg();
4425 errdefer self.register_manager.unlockReg(src_addr_lock);
4426
4427 try self.genSetReg(Type.usize, src_addr_reg, src_mcv.address());
4428 break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock };
4429 },
4430 .air_ref => |src_ref| return self.genCopy(
4431 ty,
4432 dst_mcv,
4433 try self.resolveInst(src_ref),
4434 ),
4435 else => unreachable,
4436 };
4437 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
4438
4439 var part_disp: i32 = 0;
4440 for (dst_regs, try self.splitType(ty), 0..) |dst_reg, dst_ty, part_i| {
4441 try self.genSetReg(dst_ty, dst_reg, switch (src_mcv) {
4442 .register_pair => |src_regs| .{ .register = src_regs[part_i] },
4443 .memory, .indirect, .load_frame => src_mcv.address().offset(part_disp).deref(),
4444 .load_symbol => .{ .indirect = .{
4445 .reg = src_info.?.addr_reg,
4446 .off = part_disp,
4447 } },
4448 else => unreachable,
4449 });
4450 part_disp += @intCast(dst_ty.abiSize(zcu));
4451 }
4452 },
4453 else => return self.fail("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }),
4454 }
22604455}
22614456
2262/// Sets the value without any modifications to register allocation metadata or stack allocation metadata.
2263fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
2264 switch (loc) {
4457fn genSetStack(
4458 self: *Self,
4459 ty: Type,
4460 frame: FrameAddr,
4461 src_mcv: MCValue,
4462) InnerError!void {
4463 const zcu = self.bin_file.comp.module.?;
4464 const abi_size: u32 = @intCast(ty.abiSize(zcu));
4465
4466 switch (src_mcv) {
22654467 .none => return,
2266 .register => |reg| return self.genSetReg(ty, reg, val),
2267 .stack_offset => |off| return self.genSetStack(ty, off, val),
2268 .memory => {
2269 return self.fail("TODO implement setRegOrMem for memory", .{});
4468 .dead => unreachable,
4469 .undef => {
4470 if (!self.wantSafety()) return;
4471 try self.genSetStack(ty, frame, .{ .immediate = 0xaaaaaaaaaaaaaaaa });
22704472 },
2271 else => unreachable,
4473 .immediate,
4474 .lea_frame,
4475 => {
4476 // TODO: remove this lock in favor of a copyToTmpRegister when we load 64 bit immediates with
4477 // a register allocation.
4478 const reg, const reg_lock = try self.allocReg();
4479 defer self.register_manager.unlockReg(reg_lock);
4480
4481 try self.genSetReg(ty, reg, src_mcv);
4482
4483 return self.genSetStack(ty, frame, .{ .register = reg });
4484 },
4485 .register => |reg| {
4486 switch (abi_size) {
4487 1, 2, 4, 8 => {
4488 _ = try self.addInst(.{
4489 .tag = .pseudo,
4490 .ops = .pseudo_store_rm,
4491 .data = .{ .rm = .{
4492 .r = reg,
4493 .m = .{
4494 .base = .{ .frame = frame.index },
4495 .mod = .{
4496 .rm = .{
4497 .size = self.memSize(ty),
4498 .disp = frame.off,
4499 },
4500 },
4501 },
4502 } },
4503 });
4504 },
4505 else => unreachable, // register can hold a max of 8 bytes
4506 }
4507 },
4508 .register_pair => |pair| {
4509 var part_disp: i32 = frame.off;
4510 for (try self.splitType(ty), pair) |src_ty, src_reg| {
4511 try self.genSetStack(
4512 src_ty,
4513 .{ .index = frame.index, .off = part_disp },
4514 .{ .register = src_reg },
4515 );
4516 part_disp += @intCast(src_ty.abiSize(zcu));
4517 }
4518 },
4519 .load_frame,
4520 .indirect,
4521 .load_symbol,
4522 => {
4523 if (abi_size <= 8) {
4524 const reg = try self.copyToTmpRegister(ty, src_mcv);
4525 return self.genSetStack(ty, frame, .{ .register = reg });
4526 }
4527
4528 try self.genInlineMemcpy(
4529 .{ .lea_frame = frame },
4530 src_mcv.address(),
4531 .{ .immediate = abi_size },
4532 );
4533 },
4534 .air_ref => |ref| try self.genSetStack(ty, frame, try self.resolveInst(ref)),
4535 else => return self.fail("TODO: genSetStack {s}", .{@tagName(src_mcv)}),
22724536 }
22734537}
22744538
2275fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
2276 _ = ty;
2277 _ = stack_offset;
2278 _ = mcv;
2279 return self.fail("TODO implement getSetStack for {}", .{self.target.cpu.arch});
4539fn genInlineMemcpy(
4540 self: *Self,
4541 dst_ptr: MCValue,
4542 src_ptr: MCValue,
4543 len: MCValue,
4544) !void {
4545 const regs = try self.register_manager.allocRegs(4, .{null} ** 4, tp);
4546 const locks = self.register_manager.lockRegsAssumeUnused(4, regs);
4547 defer for (locks) |lock| self.register_manager.unlockReg(lock);
4548
4549 const count = regs[0];
4550 const tmp = regs[1];
4551 const src = regs[2];
4552 const dst = regs[3];
4553
4554 try self.genSetReg(Type.usize, count, len);
4555 try self.genSetReg(Type.usize, src, src_ptr);
4556 try self.genSetReg(Type.usize, dst, dst_ptr);
4557
4558 // lb tmp, 0(src)
4559 const first_inst = try self.addInst(.{
4560 .tag = .lb,
4561 .ops = .rri,
4562 .data = .{
4563 .i_type = .{
4564 .rd = tmp,
4565 .rs1 = src,
4566 .imm12 = Immediate.s(0),
4567 },
4568 },
4569 });
4570
4571 // sb tmp, 0(dst)
4572 _ = try self.addInst(.{
4573 .tag = .sb,
4574 .ops = .rri,
4575 .data = .{
4576 .i_type = .{
4577 .rd = dst,
4578 .rs1 = tmp,
4579 .imm12 = Immediate.s(0),
4580 },
4581 },
4582 });
4583
4584 // dec count by 1
4585 _ = try self.addInst(.{
4586 .tag = .addi,
4587 .ops = .rri,
4588 .data = .{
4589 .i_type = .{
4590 .rd = count,
4591 .rs1 = count,
4592 .imm12 = Immediate.s(-1),
4593 },
4594 },
4595 });
4596
4597 // branch if count is 0
4598 _ = try self.addInst(.{
4599 .tag = .beq,
4600 .ops = .rr_inst,
4601 .data = .{
4602 .b_type = .{
4603 .inst = @intCast(self.mir_instructions.len + 4), // points after the last inst
4604 .rs1 = count,
4605 .rs2 = .zero,
4606 },
4607 },
4608 });
4609
4610 // increment the pointers
4611 _ = try self.addInst(.{
4612 .tag = .addi,
4613 .ops = .rri,
4614 .data = .{
4615 .i_type = .{
4616 .rd = src,
4617 .rs1 = src,
4618 .imm12 = Immediate.s(1),
4619 },
4620 },
4621 });
4622
4623 _ = try self.addInst(.{
4624 .tag = .addi,
4625 .ops = .rri,
4626 .data = .{
4627 .i_type = .{
4628 .rd = dst,
4629 .rs1 = dst,
4630 .imm12 = Immediate.s(1),
4631 },
4632 },
4633 });
4634
4635 // jump back to start of loop
4636 _ = try self.addInst(.{
4637 .tag = .pseudo,
4638 .ops = .pseudo_j,
4639 .data = .{
4640 .inst = first_inst,
4641 },
4642 });
22804643}
22814644
2282fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
2283 switch (mcv) {
4645/// Sets the value of `src_mcv` into `reg`. Assumes you have a lock on it.
4646fn genSetReg(self: *Self, ty: Type, reg: Register, src_mcv: MCValue) InnerError!void {
4647 const zcu = self.bin_file.comp.module.?;
4648 const abi_size: u32 = @intCast(ty.abiSize(zcu));
4649
4650 if (abi_size > 8) return self.fail("tried to set reg with size {}", .{abi_size});
4651
4652 switch (src_mcv) {
22844653 .dead => unreachable,
2285 .ptr_stack_offset => unreachable,
22864654 .unreach, .none => return, // Nothing to do.
22874655 .undef => {
22884656 if (!self.wantSafety())
......@@ -2295,10 +4663,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
22954663 if (math.minInt(i12) <= x and x <= math.maxInt(i12)) {
22964664 _ = try self.addInst(.{
22974665 .tag = .addi,
4666 .ops = .rri,
22984667 .data = .{ .i_type = .{
22994668 .rd = reg,
23004669 .rs1 = .zero,
2301 .imm12 = @intCast(x),
4670 .imm12 = Immediate.s(@intCast(x)),
23024671 } },
23034672 });
23044673 } else if (math.minInt(i32) <= x and x <= math.maxInt(i32)) {
......@@ -2306,26 +4675,56 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
23064675 const carry: i32 = if (lo12 < 0) 1 else 0;
23074676 const hi20: i20 = @truncate((x >> 12) +% carry);
23084677
2309 // TODO: add test case for 32-bit immediate
23104678 _ = try self.addInst(.{
23114679 .tag = .lui,
4680 .ops = .ri,
23124681 .data = .{ .u_type = .{
23134682 .rd = reg,
2314 .imm20 = hi20,
4683 .imm20 = Immediate.s(hi20),
23154684 } },
23164685 });
23174686 _ = try self.addInst(.{
23184687 .tag = .addi,
4688 .ops = .rri,
23194689 .data = .{ .i_type = .{
23204690 .rd = reg,
23214691 .rs1 = reg,
2322 .imm12 = lo12,
4692 .imm12 = Immediate.s(lo12),
23234693 } },
23244694 });
23254695 } else {
2326 // li rd, immediate
2327 // "Myriad sequences"
2328 return self.fail("TODO genSetReg 33-64 bit immediates for riscv64", .{}); // glhf
4696 // TODO: use a more advanced myriad seq to do this without a reg.
4697 // see: https://github.com/llvm/llvm-project/blob/081a66ffacfe85a37ff775addafcf3371e967328/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp#L224
4698
4699 const temp, const temp_lock = try self.allocReg();
4700 defer self.register_manager.unlockReg(temp_lock);
4701
4702 const lo32: i32 = @truncate(x);
4703 const carry: i32 = if (lo32 < 0) 1 else 0;
4704 const hi32: i32 = @truncate((x >> 32) +% carry);
4705
4706 try self.genSetReg(Type.i32, temp, .{ .immediate = @bitCast(@as(i64, lo32)) });
4707 try self.genSetReg(Type.i32, reg, .{ .immediate = @bitCast(@as(i64, hi32)) });
4708
4709 _ = try self.addInst(.{
4710 .tag = .slli,
4711 .ops = .rri,
4712 .data = .{ .i_type = .{
4713 .rd = reg,
4714 .rs1 = reg,
4715 .imm12 = Immediate.s(32),
4716 } },
4717 });
4718
4719 _ = try self.addInst(.{
4720 .tag = .add,
4721 .ops = .rrr,
4722 .data = .{ .r_type = .{
4723 .rd = reg,
4724 .rs1 = reg,
4725 .rs2 = temp,
4726 } },
4727 });
23294728 }
23304729 },
23314730 .register => |src_reg| {
......@@ -2335,62 +4734,160 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
23354734
23364735 // mov reg, src_reg
23374736 _ = try self.addInst(.{
2338 .tag = .mv,
4737 .tag = .pseudo,
4738 .ops = .pseudo_mv,
23394739 .data = .{ .rr = .{
23404740 .rd = reg,
23414741 .rs = src_reg,
23424742 } },
23434743 });
23444744 },
4745 .register_pair => |pair| try self.genSetReg(ty, reg, .{ .register = pair[0] }),
23454746 .memory => |addr| {
2346 // The value is in memory at a hard-coded address.
2347 // If the type is a pointer, it means the pointer address is at this memory location.
23484747 try self.genSetReg(ty, reg, .{ .immediate = addr });
23494748
23504749 _ = try self.addInst(.{
23514750 .tag = .ld,
4751 .ops = .rri,
23524752 .data = .{ .i_type = .{
23534753 .rd = reg,
23544754 .rs1 = reg,
2355 .imm12 = 0,
4755 .imm12 = Immediate.s(0),
4756 } },
4757 });
4758 },
4759 .load_frame => |frame| {
4760 _ = try self.addInst(.{
4761 .tag = .pseudo,
4762 .ops = .pseudo_load_rm,
4763 .data = .{ .rm = .{
4764 .r = reg,
4765 .m = .{
4766 .base = .{ .frame = frame.index },
4767 .mod = .{
4768 .rm = .{
4769 .size = self.memSize(ty),
4770 .disp = frame.off,
4771 },
4772 },
4773 },
4774 } },
4775 });
4776 },
4777 .lea_frame => |frame| {
4778 _ = try self.addInst(.{
4779 .tag = .pseudo,
4780 .ops = .pseudo_lea_rm,
4781 .data = .{ .rm = .{
4782 .r = reg,
4783 .m = .{
4784 .base = .{ .frame = frame.index },
4785 .mod = .{
4786 .rm = .{
4787 .size = self.memSize(ty),
4788 .disp = frame.off,
4789 },
4790 },
4791 },
4792 } },
4793 });
4794 },
4795 .load_symbol => {
4796 try self.genSetReg(ty, reg, src_mcv.address());
4797 try self.genSetReg(ty, reg, .{ .indirect = .{ .reg = reg } });
4798 },
4799 .indirect => |reg_off| {
4800 const load_tag: Mir.Inst.Tag = switch (abi_size) {
4801 1 => .lb,
4802 2 => .lh,
4803 4 => .lw,
4804 8 => .ld,
4805 else => return self.fail("TODO: genSetReg for size {d}", .{abi_size}),
4806 };
4807
4808 _ = try self.addInst(.{
4809 .tag = load_tag,
4810 .ops = .rri,
4811 .data = .{ .i_type = .{
4812 .rd = reg,
4813 .rs1 = reg_off.reg,
4814 .imm12 = Immediate.s(reg_off.off),
23564815 } },
23574816 });
2358 // LOAD imm=[i12 offset = 0], rs1 =
4817 },
4818 .lea_symbol => |sym_off| {
4819 assert(sym_off.off == 0);
4820
4821 const atom_index = try self.symbolIndex();
23594822
2360 // return self.fail("TODO implement genSetReg memory for riscv64");
4823 _ = try self.addInst(.{
4824 .tag = .pseudo,
4825 .ops = .pseudo_load_symbol,
4826 .data = .{ .payload = try self.addExtra(Mir.LoadSymbolPayload{
4827 .register = reg.id(),
4828 .atom_index = atom_index,
4829 .sym_index = sym_off.sym,
4830 }) },
4831 });
23614832 },
2362 else => return self.fail("TODO implement getSetReg for riscv64 {}", .{mcv}),
4833 .air_ref => |ref| try self.genSetReg(ty, reg, try self.resolveInst(ref)),
4834 else => return self.fail("TODO: genSetReg {s}", .{@tagName(src_mcv)}),
23634835 }
23644836}
23654837
23664838fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {
23674839 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2368 const result = try self.resolveInst(un_op);
4840 const result = result: {
4841 const src_mcv = try self.resolveInst(un_op);
4842 if (self.reuseOperand(inst, un_op, 0, src_mcv)) break :result src_mcv;
4843
4844 const dst_mcv = try self.allocRegOrMem(inst, true);
4845 const dst_ty = self.typeOfIndex(inst);
4846 try self.genCopy(dst_ty, dst_mcv, src_mcv);
4847 break :result dst_mcv;
4848 };
23694849 return self.finishAir(inst, result, .{ un_op, .none, .none });
23704850}
23714851
23724852fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
2373 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2374 const result = if (self.liveness.isUnused(inst)) .dead else result: {
2375 const operand = try self.resolveInst(ty_op.operand);
2376 if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand;
4853 const zcu = self.bin_file.comp.module.?;
23774854
2378 const operand_lock = switch (operand) {
2379 .register => |reg| self.register_manager.lockReg(reg),
2380 else => null,
4855 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4856 const result = if (self.liveness.isUnused(inst)) .unreach else result: {
4857 const src_mcv = try self.resolveInst(ty_op.operand);
4858
4859 const dst_ty = self.typeOfIndex(inst);
4860 const src_ty = self.typeOf(ty_op.operand);
4861
4862 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
4863 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
4864
4865 const dst_mcv = if (dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and
4866 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
4867 const dst_mcv = try self.allocRegOrMem(inst, true);
4868 try self.genCopy(switch (math.order(dst_ty.abiSize(zcu), src_ty.abiSize(zcu))) {
4869 .lt => dst_ty,
4870 .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty,
4871 .gt => src_ty,
4872 }, dst_mcv, src_mcv);
4873 break :dst dst_mcv;
23814874 };
2382 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
23834875
2384 const dest = try self.allocRegOrMem(inst, true);
2385 try self.setRegOrMem(self.typeOfIndex(inst), dest, operand);
2386 break :result dest;
4876 if (dst_ty.isAbiInt(zcu) and src_ty.isAbiInt(zcu) and
4877 dst_ty.intInfo(zcu).signedness == src_ty.intInfo(zcu).signedness) break :result dst_mcv;
4878
4879 const abi_size = dst_ty.abiSize(zcu);
4880 const bit_size = dst_ty.bitSize(zcu);
4881 if (abi_size * 8 <= bit_size) break :result dst_mcv;
4882
4883 return self.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(zcu), dst_ty.fmt(zcu) });
23874884 };
23884885 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
23894886}
23904887
23914888fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
23924889 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2393 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airArrayToSlice for {}", .{
4890 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airArrayToSlice for {}", .{
23944891 self.target.cpu.arch,
23954892 });
23964893 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -2398,7 +4895,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
23984895
23994896fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
24004897 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2401 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFloatFromInt for {}", .{
4898 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airFloatFromInt for {}", .{
24024899 self.target.cpu.arch,
24034900 });
24044901 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -2406,7 +4903,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
24064903
24074904fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
24084905 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2409 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airIntFromFloat for {}", .{
4906 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airIntFromFloat for {}", .{
24104907 self.target.cpu.arch,
24114908 });
24124909 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -2456,7 +4953,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
24564953fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
24574954 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
24584955 const operand = try self.resolveInst(un_op);
2459 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
4956 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else {
24604957 _ = operand;
24614958 return self.fail("TODO implement airTagName for riscv64", .{});
24624959 };
......@@ -2464,49 +4961,98 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
24644961}
24654962
24664963fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
4964 const zcu = self.bin_file.comp.module.?;
24674965 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2468 const operand = try self.resolveInst(un_op);
2469 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
2470 _ = operand;
2471 return self.fail("TODO implement airErrorName for riscv64", .{});
2472 };
2473 return self.finishAir(inst, result, .{ un_op, .none, .none });
4966
4967 const err_ty = self.typeOf(un_op);
4968 const err_mcv = try self.resolveInst(un_op);
4969
4970 const err_reg = try self.copyToTmpRegister(err_ty, err_mcv);
4971 const err_lock = self.register_manager.lockRegAssumeUnused(err_reg);
4972 defer self.register_manager.unlockReg(err_lock);
4973
4974 const addr_reg, const addr_lock = try self.allocReg();
4975 defer self.register_manager.unlockReg(addr_lock);
4976
4977 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, zcu);
4978 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4979 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|
4980 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
4981 const sym = elf_file.symbol(sym_index);
4982 try self.genSetReg(Type.usize, addr_reg, .{ .load_symbol = .{ .sym = sym.esym_index } });
4983 } else {
4984 return self.fail("TODO: riscv non-elf", .{});
4985 }
4986
4987 const start_reg, const start_lock = try self.allocReg();
4988 defer self.register_manager.unlockReg(start_lock);
4989
4990 const end_reg, const end_lock = try self.allocReg();
4991 defer self.register_manager.unlockReg(end_lock);
4992
4993 _ = start_reg;
4994 _ = end_reg;
4995
4996 return self.fail("TODO: airErrorName", .{});
24744997}
24754998
24764999fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
24775000 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2478 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSplat for riscv64", .{});
5001 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airSplat for riscv64", .{});
24795002 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
24805003}
24815004
24825005fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
24835006 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
24845007 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
2485 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSelect for riscv64", .{});
5008 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airSelect for riscv64", .{});
24865009 return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs });
24875010}
24885011
24895012fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
24905013 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2491 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for riscv64", .{});
5014 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airShuffle for riscv64", .{});
24925015 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
24935016}
24945017
24955018fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
24965019 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
2497 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airReduce for riscv64", .{});
5020 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else return self.fail("TODO implement airReduce for riscv64", .{});
24985021 return self.finishAir(inst, result, .{ reduce.operand, .none, .none });
24995022}
25005023
25015024fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
2502 const mod = self.bin_file.comp.module.?;
2503 const vector_ty = self.typeOfIndex(inst);
2504 const len = vector_ty.vectorLen(mod);
5025 const zcu = self.bin_file.comp.module.?;
5026 const result_ty = self.typeOfIndex(inst);
5027 const len: usize = @intCast(result_ty.arrayLen(zcu));
25055028 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
25065029 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
2507 const result: MCValue = res: {
2508 if (self.liveness.isUnused(inst)) break :res MCValue.dead;
2509 return self.fail("TODO implement airAggregateInit for riscv64", .{});
5030 const result: MCValue = result: {
5031 switch (result_ty.zigTypeTag(zcu)) {
5032 .Struct => {
5033 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(result_ty, zcu));
5034
5035 if (result_ty.containerLayout(zcu) == .@"packed") {} else for (elements, 0..) |elem, elem_i| {
5036 if ((try result_ty.structFieldValueComptime(zcu, elem_i)) != null) continue;
5037
5038 const elem_ty = result_ty.structFieldType(elem_i, zcu);
5039 const elem_off: i32 = @intCast(result_ty.structFieldOffset(elem_i, zcu));
5040 const elem_mcv = try self.resolveInst(elem);
5041
5042 const elem_frame: FrameAddr = .{
5043 .index = frame_index,
5044 .off = elem_off,
5045 };
5046 try self.genSetStack(
5047 elem_ty,
5048 elem_frame,
5049 elem_mcv,
5050 );
5051 }
5052 },
5053 else => return self.fail("TODO: airAggregateInit {}", .{result_ty.fmt(zcu)}),
5054 }
5055 break :result .{ .register = .zero };
25105056 };
25115057
25125058 if (elements.len <= Liveness.bpi - 1) {
......@@ -2514,11 +5060,9 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
25145060 @memcpy(buf[0..elements.len], elements);
25155061 return self.finishAir(inst, result, buf);
25165062 }
2517 var bt = try self.iterateBigTomb(inst, elements.len);
2518 for (elements) |elem| {
2519 bt.feed(elem);
2520 }
2521 return bt.finishAir(result);
5063 var bt = self.liveness.iterateBigTomb(inst);
5064 for (elements) |elem| try self.feed(&bt, elem);
5065 return self.finishAirResult(inst, result);
25225066}
25235067
25245068fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
......@@ -2531,57 +5075,68 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
25315075
25325076fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
25335077 const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
2534 return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
5078 // TODO: RISC-V does have prefetch instruction variants.
5079 // see here: https://raw.githubusercontent.com/riscv/riscv-CMOs/master/specifications/cmobase-v1.0.1.pdf
5080 return self.finishAir(inst, .unreach, .{ prefetch.ptr, .none, .none });
25355081}
25365082
25375083fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
25385084 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
25395085 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
2540 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
5086 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else {
25415087 return self.fail("TODO implement airMulAdd for riscv64", .{});
25425088 };
25435089 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, pl_op.operand });
25445090}
25455091
2546fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
2547 const mod = self.bin_file.comp.module.?;
5092fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
5093 const zcu = self.bin_file.comp.module.?;
25485094
25495095 // If the type has no codegen bits, no need to store it.
2550 const inst_ty = self.typeOf(inst);
2551 if (!inst_ty.hasRuntimeBits(mod))
2552 return MCValue{ .none = {} };
2553
2554 const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);
5096 const inst_ty = self.typeOf(ref);
5097 if (!inst_ty.hasRuntimeBits(zcu))
5098 return .none;
5099
5100 const mcv = if (ref.toIndex()) |inst| mcv: {
5101 break :mcv self.inst_tracking.getPtr(inst).?.short;
5102 } else mcv: {
5103 const ip_index = ref.toInterned().?;
5104 const gop = try self.const_tracking.getOrPut(self.gpa, ip_index);
5105 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(
5106 try self.genTypedValue(Value.fromInterned(ip_index)),
5107 );
5108 break :mcv gop.value_ptr.short;
5109 };
25555110
2556 return self.getResolvedInstValue(inst_index);
5111 return mcv;
25575112}
25585113
2559fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
2560 // Treat each stack item as a "layer" on top of the previous one.
2561 var i: usize = self.branch_stack.items.len;
2562 while (true) {
2563 i -= 1;
2564 if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| {
2565 assert(mcv != .dead);
2566 return mcv;
2567 }
2568 }
5114fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {
5115 const tracking = self.inst_tracking.getPtr(inst).?;
5116 return switch (tracking.short) {
5117 .none, .unreach, .dead => unreachable,
5118 else => tracking,
5119 };
25695120}
25705121
25715122fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
2572 const mod = self.bin_file.comp.module.?;
2573 const mcv: MCValue = switch (try codegen.genTypedValue(
5123 const zcu = self.bin_file.comp.module.?;
5124 const result = try codegen.genTypedValue(
25745125 self.bin_file,
25755126 self.src_loc,
25765127 val,
2577 mod.funcOwnerDeclIndex(self.func_index),
2578 )) {
5128 zcu.funcOwnerDeclIndex(self.func_index),
5129 );
5130 const mcv: MCValue = switch (result) {
25795131 .mcv => |mcv| switch (mcv) {
25805132 .none => .none,
25815133 .undef => .undef,
2582 .load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO
5134 .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } },
25835135 .immediate => |imm| .{ .immediate = imm },
25845136 .memory => |addr| .{ .memory = addr },
5137 .load_got, .load_direct, .load_tlv => {
5138 return self.fail("TODO: genTypedValue {s}", .{@tagName(mcv)});
5139 },
25855140 },
25865141 .fail => |msg| {
25875142 self.err_msg = msg;
......@@ -2593,8 +5148,8 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
25935148
25945149const CallMCValues = struct {
25955150 args: []MCValue,
2596 return_value: MCValue,
2597 stack_byte_count: u32,
5151 return_value: InstTracking,
5152 stack_byte_count: u31,
25985153 stack_align: Alignment,
25995154
26005155 fn deinit(self: *CallMCValues, func: *Self) void {
......@@ -2604,94 +5159,134 @@ const CallMCValues = struct {
26045159};
26055160
26065161/// Caller must call `CallMCValues.deinit`.
2607fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
2608 const mod = self.bin_file.comp.module.?;
2609 const ip = &mod.intern_pool;
2610 const fn_info = mod.typeToFunc(fn_ty).?;
5162fn resolveCallingConventionValues(
5163 self: *Self,
5164 fn_info: InternPool.Key.FuncType,
5165) !CallMCValues {
5166 const zcu = self.bin_file.comp.module.?;
5167 const ip = &zcu.intern_pool;
5168
5169 const param_types = try self.gpa.alloc(Type, fn_info.param_types.len);
5170 defer self.gpa.free(param_types);
5171
5172 for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src| {
5173 dest.* = Type.fromInterned(src);
5174 }
5175
26115176 const cc = fn_info.cc;
26125177 var result: CallMCValues = .{
2613 .args = try self.gpa.alloc(MCValue, fn_info.param_types.len),
5178 .args = try self.gpa.alloc(MCValue, param_types.len),
26145179 // These undefined values must be populated before returning from this function.
26155180 .return_value = undefined,
2616 .stack_byte_count = undefined,
5181 .stack_byte_count = 0,
26175182 .stack_align = undefined,
26185183 };
26195184 errdefer self.gpa.free(result.args);
26205185
2621 const ret_ty = fn_ty.fnReturnType(mod);
5186 const ret_ty = Type.fromInterned(fn_info.return_type);
26225187
26235188 switch (cc) {
26245189 .Naked => {
26255190 assert(result.args.len == 0);
2626 result.return_value = .{ .unreach = {} };
2627 result.stack_byte_count = 0;
2628 result.stack_align = .@"1";
2629 return result;
5191 result.return_value = InstTracking.init(.unreach);
5192 result.stack_align = .@"8";
26305193 },
2631 .Unspecified, .C => {
2632 // LP64D ABI
2633 //
2634 // TODO make this generic with other ABIs, in particular
2635 // with different hardware floating-point calling
2636 // conventions
2637 var next_register: usize = 0;
2638 var next_stack_offset: u32 = 0;
2639 // TODO: this is never assigned, which is a bug, but I don't know how this code works
2640 // well enough to try and fix it. I *think* `next_register += next_stack_offset` is
2641 // supposed to be `next_stack_offset += param_size` in every case where it appears.
2642 _ = &next_stack_offset;
2643
2644 const argument_registers = [_]Register{ .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7 };
2645
2646 for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
2647 const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));
2648 if (param_size <= 8) {
2649 if (next_register < argument_registers.len) {
2650 result_arg.* = .{ .register = argument_registers[next_register] };
2651 next_register += 1;
2652 } else {
2653 result_arg.* = .{ .stack_offset = next_stack_offset };
2654 next_register += next_stack_offset;
2655 }
2656 } else if (param_size <= 16) {
2657 if (next_register < argument_registers.len - 1) {
2658 return self.fail("TODO MCValues with 2 registers", .{});
2659 } else if (next_register < argument_registers.len) {
2660 return self.fail("TODO MCValues split register + stack", .{});
2661 } else {
2662 result_arg.* = .{ .stack_offset = next_stack_offset };
2663 next_register += next_stack_offset;
2664 }
2665 } else {
2666 result_arg.* = .{ .stack_offset = next_stack_offset };
2667 next_register += next_stack_offset;
2668 }
5194 .C, .Unspecified => {
5195 if (result.args.len > 8) {
5196 return self.fail("RISC-V calling convention does not support more than 8 arguments", .{});
26695197 }
26705198
2671 result.stack_byte_count = next_stack_offset;
5199 var ret_int_reg_i: u32 = 0;
5200 var param_int_reg_i: u32 = 0;
5201
26725202 result.stack_align = .@"16";
2673 },
2674 else => return self.fail("TODO implement function parameters for {} on riscv64", .{cc}),
2675 }
26765203
2677 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
2678 result.return_value = .{ .unreach = {} };
2679 } else if (!ret_ty.hasRuntimeBits(mod)) {
2680 result.return_value = .{ .none = {} };
2681 } else switch (cc) {
2682 .Naked => unreachable,
2683 .Unspecified, .C => {
2684 const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod));
2685 if (ret_ty_size <= 8) {
2686 result.return_value = .{ .register = .a0 };
2687 } else if (ret_ty_size <= 16) {
2688 return self.fail("TODO support MCValue 2 registers", .{});
5204 // Return values
5205 if (ret_ty.zigTypeTag(zcu) == .NoReturn) {
5206 result.return_value = InstTracking.init(.unreach);
5207 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5208 result.return_value = InstTracking.init(.none);
26895209 } else {
2690 return self.fail("TODO support return by reference", .{});
5210 var ret_tracking: [2]InstTracking = undefined;
5211 var ret_tracking_i: usize = 0;
5212
5213 const classes = mem.sliceTo(&abi.classifySystem(ret_ty, zcu), .none);
5214
5215 for (classes) |class| switch (class) {
5216 .integer => {
5217 const ret_int_reg = abi.function_ret_regs[ret_int_reg_i];
5218 ret_int_reg_i += 1;
5219
5220 ret_tracking[ret_tracking_i] = InstTracking.init(.{ .register = ret_int_reg });
5221 ret_tracking_i += 1;
5222 },
5223 .memory => {
5224 const ret_int_reg = abi.function_ret_regs[ret_int_reg_i];
5225 ret_int_reg_i += 1;
5226 const ret_indirect_reg = abi.function_arg_regs[param_int_reg_i];
5227 param_int_reg_i += 1;
5228
5229 ret_tracking[ret_tracking_i] = .{
5230 .short = .{ .indirect = .{ .reg = ret_int_reg } },
5231 .long = .{ .indirect = .{ .reg = ret_indirect_reg } },
5232 };
5233 ret_tracking_i += 1;
5234 },
5235 else => return self.fail("TODO: C calling convention return class {}", .{class}),
5236 };
5237
5238 result.return_value = switch (ret_tracking_i) {
5239 else => return self.fail("ty {} took {} tracking return indices", .{ ret_ty.fmt(zcu), ret_tracking_i }),
5240 1 => ret_tracking[0],
5241 2 => InstTracking.init(.{ .register_pair = .{
5242 ret_tracking[0].short.register, ret_tracking[1].short.register,
5243 } }),
5244 };
5245 }
5246
5247 for (param_types, result.args) |ty, *arg| {
5248 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
5249
5250 var arg_mcv: [2]MCValue = undefined;
5251 var arg_mcv_i: usize = 0;
5252
5253 const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none);
5254
5255 for (classes) |class| switch (class) {
5256 .integer => {
5257 const param_int_regs = abi.function_arg_regs;
5258 if (param_int_reg_i >= param_int_regs.len) break;
5259
5260 const param_int_reg = param_int_regs[param_int_reg_i];
5261 param_int_reg_i += 1;
5262
5263 arg_mcv[arg_mcv_i] = .{ .register = param_int_reg };
5264 arg_mcv_i += 1;
5265 },
5266 .memory => {
5267 const param_int_regs = abi.function_arg_regs;
5268 const param_int_reg = param_int_regs[param_int_reg_i];
5269
5270 arg_mcv[arg_mcv_i] = .{ .indirect = .{ .reg = param_int_reg } };
5271 arg_mcv_i += 1;
5272 },
5273 else => return self.fail("TODO: C calling convention arg class {}", .{class}),
5274 } else {
5275 arg.* = switch (arg_mcv_i) {
5276 else => return self.fail("ty {} took {} tracking arg indices", .{ ty.fmt(zcu), arg_mcv_i }),
5277 1 => arg_mcv[0],
5278 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } },
5279 };
5280 continue;
5281 }
5282
5283 return self.fail("TODO: pass args by stack", .{});
26915284 }
26925285 },
2693 else => return self.fail("TODO implement function return values for {}", .{cc}),
5286 else => return self.fail("TODO implement function parameters for {} on riscv64", .{cc}),
26945287 }
5288
5289 result.stack_byte_count = @intCast(result.stack_align.forward(result.stack_byte_count));
26955290 return result;
26965291}
26975292
......@@ -2727,11 +5322,37 @@ fn parseRegName(name: []const u8) ?Register {
27275322}
27285323
27295324fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
2730 const mod = self.bin_file.comp.module.?;
2731 return self.air.typeOf(inst, &mod.intern_pool);
5325 const zcu = self.bin_file.comp.module.?;
5326 return self.air.typeOf(inst, &zcu.intern_pool);
27325327}
27335328
27345329fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
2735 const mod = self.bin_file.comp.module.?;
2736 return self.air.typeOfIndex(inst, &mod.intern_pool);
5330 const zcu = self.bin_file.comp.module.?;
5331 return self.air.typeOfIndex(inst, &zcu.intern_pool);
5332}
5333
5334fn hasFeature(self: *Self, feature: Target.riscv.Feature) bool {
5335 return Target.riscv.featureSetHas(self.target.cpu.features, feature);
5336}
5337
5338pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Module) u64 {
5339 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
5340 const payload_align = payload_ty.abiAlignment(zcu);
5341 const error_align = Type.anyerror.abiAlignment(zcu);
5342 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5343 return 0;
5344 } else {
5345 return payload_align.forward(Type.anyerror.abiSize(zcu));
5346 }
5347}
5348
5349pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Module) u64 {
5350 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
5351 const payload_align = payload_ty.abiAlignment(zcu);
5352 const error_align = Type.anyerror.abiAlignment(zcu);
5353 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5354 return error_align.forward(payload_ty.abiSize(zcu));
5355 } else {
5356 return 0;
5357 }
27375358}
src/arch/riscv64/Emit.zig+156-184
......@@ -1,25 +1,7 @@
1//! This file contains the functionality for lowering RISCV64 MIR into
2//! machine code
1//! This file contains the functionality for emitting RISC-V MIR as machine code
32
4const Emit = @This();
5const std = @import("std");
6const math = std.math;
7const Mir = @import("Mir.zig");
8const bits = @import("bits.zig");
9const link = @import("../../link.zig");
10const Module = @import("../../Module.zig");
11const ErrorMsg = Module.ErrorMsg;
12const assert = std.debug.assert;
13const Instruction = bits.Instruction;
14const Register = bits.Register;
15const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
16
17mir: Mir,
18bin_file: *link.File,
3lower: Lower,
194debug_output: DebugInfoOutput,
20target: *const std.Target,
21err_msg: ?*ErrorMsg = null,
22src_loc: Module.SrcLoc,
235code: *std.ArrayList(u8),
246
257prev_di_line: u32,
......@@ -27,195 +9,185 @@ prev_di_column: u32,
279/// Relative to the beginning of `code`.
2810prev_di_pc: usize,
2911
30const InnerError = error{
31 OutOfMemory,
12code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .{},
13relocs: std.ArrayListUnmanaged(Reloc) = .{},
14
15pub const Error = Lower.Error || error{
3216 EmitFail,
3317};
3418
35pub fn emitMir(
36 emit: *Emit,
37) InnerError!void {
38 const mir_tags = emit.mir.instructions.items(.tag);
39
40 // Emit machine code
41 for (mir_tags, 0..) |tag, index| {
42 const inst = @as(u32, @intCast(index));
43 switch (tag) {
44 .add => try emit.mirRType(inst),
45 .sub => try emit.mirRType(inst),
46
47 .addi => try emit.mirIType(inst),
48 .jalr => try emit.mirIType(inst),
49 .ld => try emit.mirIType(inst),
50 .sd => try emit.mirIType(inst),
51
52 .ebreak => try emit.mirSystem(inst),
53 .ecall => try emit.mirSystem(inst),
54 .unimp => try emit.mirSystem(inst),
55
56 .dbg_line => try emit.mirDbgLine(inst),
57
58 .dbg_prologue_end => try emit.mirDebugPrologueEnd(),
59 .dbg_epilogue_begin => try emit.mirDebugEpilogueBegin(),
60
61 .mv => try emit.mirRR(inst),
62
63 .nop => try emit.mirNop(inst),
64 .ret => try emit.mirNop(inst),
65
66 .lui => try emit.mirUType(inst),
19pub fn emitMir(emit: *Emit) Error!void {
20 log.debug("mir instruction len: {}", .{emit.lower.mir.instructions.len});
21 for (0..emit.lower.mir.instructions.len) |mir_i| {
22 const mir_index: Mir.Inst.Index = @intCast(mir_i);
23 try emit.code_offset_mapping.putNoClobber(
24 emit.lower.allocator,
25 mir_index,
26 @intCast(emit.code.items.len),
27 );
28 const lowered = try emit.lower.lowerMir(mir_index);
29 var lowered_relocs = lowered.relocs;
30 for (lowered.insts, 0..) |lowered_inst, lowered_index| {
31 const start_offset: u32 = @intCast(emit.code.items.len);
32 try lowered_inst.encode(emit.code.writer());
33
34 while (lowered_relocs.len > 0 and
35 lowered_relocs[0].lowered_inst_index == lowered_index) : ({
36 lowered_relocs = lowered_relocs[1..];
37 }) switch (lowered_relocs[0].target) {
38 .inst => |target| try emit.relocs.append(emit.lower.allocator, .{
39 .source = start_offset,
40 .target = target,
41 .offset = 0,
42 .enc = std.meta.activeTag(lowered_inst.encoding.data),
43 }),
44 .load_symbol_reloc => |symbol| {
45 if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
46 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
47 const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);
48 const sym = elf_file.symbol(sym_index);
49
50 var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
51 var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
52
53 if (sym.flags.needs_zig_got) {
54 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
55
56 hi_r_type = Elf.R_ZIG_GOT_HI20;
57 lo_r_type = Elf.R_ZIG_GOT_LO12;
58 }
59
60 try atom_ptr.addReloc(elf_file, .{
61 .r_offset = start_offset,
62 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
63 .r_addend = 0,
64 });
65
66 try atom_ptr.addReloc(elf_file, .{
67 .r_offset = start_offset + 4,
68 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
69 .r_addend = 0,
70 });
71 } else return emit.fail("TODO: load_symbol_reloc non-ELF", .{});
72 },
73 };
74 }
75 std.debug.assert(lowered_relocs.len == 0);
76
77 if (lowered.insts.len == 0) {
78 const mir_inst = emit.lower.mir.instructions.get(mir_index);
79 switch (mir_inst.tag) {
80 else => unreachable,
81 .pseudo => switch (mir_inst.ops) {
82 else => unreachable,
83 .pseudo_dbg_prologue_end => {
84 switch (emit.debug_output) {
85 .dwarf => |dw| {
86 try dw.setPrologueEnd();
87 log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
88 emit.prev_di_line, emit.prev_di_column,
89 });
90 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
91 },
92 .plan9 => {},
93 .none => {},
94 }
95 },
96 .pseudo_dbg_line_column => try emit.dbgAdvancePCAndLine(
97 mir_inst.data.pseudo_dbg_line_column.line,
98 mir_inst.data.pseudo_dbg_line_column.column,
99 ),
100 .pseudo_dbg_epilogue_begin => {
101 switch (emit.debug_output) {
102 .dwarf => |dw| {
103 try dw.setEpilogueBegin();
104 log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
105 emit.prev_di_line, emit.prev_di_column,
106 });
107 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
108 },
109 .plan9 => {},
110 .none => {},
111 }
112 },
113 .pseudo_dead => {},
114 },
115 }
67116 }
68117 }
118 try emit.fixupRelocs();
69119}
70120
71121pub fn deinit(emit: *Emit) void {
122 emit.relocs.deinit(emit.lower.allocator);
123 emit.code_offset_mapping.deinit(emit.lower.allocator);
72124 emit.* = undefined;
73125}
74126
75fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
76 const endian = emit.target.cpu.arch.endian();
77 std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian);
78}
79
80fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
81 @setCold(true);
82 assert(emit.err_msg == null);
83 const comp = emit.bin_file.comp;
84 const gpa = comp.gpa;
85 emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
86 return error.EmitFail;
87}
88
89fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
90 const delta_line = @as(i32, @intCast(line)) - @as(i32, @intCast(self.prev_di_line));
91 const delta_pc: usize = self.code.items.len - self.prev_di_pc;
92 switch (self.debug_output) {
93 .dwarf => |dw| {
94 try dw.advancePCAndLine(delta_line, delta_pc);
95 self.prev_di_line = line;
96 self.prev_di_column = column;
97 self.prev_di_pc = self.code.items.len;
98 },
99 .plan9 => |dbg_out| {
100 if (delta_pc <= 0) return; // only do this when the pc changes
101
102 // increasing the line number
103 try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
104 // increasing the pc
105 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
106 if (d_pc_p9 > 0) {
107 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
108 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
109 if (dbg_out.pcop_change_index) |pci|
110 dbg_out.dbg_line.items[pci] += 1;
111 dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
112 } else if (d_pc_p9 == 0) {
113 // we don't need to do anything, because adding the pc quanta does it for us
114 } else unreachable;
115 if (dbg_out.start_line == null)
116 dbg_out.start_line = self.prev_di_line;
117 dbg_out.end_line = line;
118 // only do this if the pc changed
119 self.prev_di_line = line;
120 self.prev_di_column = column;
121 self.prev_di_pc = self.code.items.len;
122 },
123 .none => {},
124 }
125}
126
127fn mirRType(emit: *Emit, inst: Mir.Inst.Index) !void {
128 const tag = emit.mir.instructions.items(.tag)[inst];
129 const r_type = emit.mir.instructions.items(.data)[inst].r_type;
130
131 switch (tag) {
132 .add => try emit.writeInstruction(Instruction.add(r_type.rd, r_type.rs1, r_type.rs2)),
133 .sub => try emit.writeInstruction(Instruction.sub(r_type.rd, r_type.rs1, r_type.rs2)),
134 else => unreachable,
135 }
136}
137
138fn mirIType(emit: *Emit, inst: Mir.Inst.Index) !void {
139 const tag = emit.mir.instructions.items(.tag)[inst];
140 const i_type = emit.mir.instructions.items(.data)[inst].i_type;
141
142 switch (tag) {
143 .addi => try emit.writeInstruction(Instruction.addi(i_type.rd, i_type.rs1, i_type.imm12)),
144 .jalr => try emit.writeInstruction(Instruction.jalr(i_type.rd, i_type.imm12, i_type.rs1)),
145 .ld => try emit.writeInstruction(Instruction.ld(i_type.rd, i_type.imm12, i_type.rs1)),
146 .sd => try emit.writeInstruction(Instruction.sd(i_type.rd, i_type.imm12, i_type.rs1)),
147 else => unreachable,
148 }
149}
127const Reloc = struct {
128 /// Offset of the instruction.
129 source: usize,
130 /// Target of the relocation.
131 target: Mir.Inst.Index,
132 /// Offset of the relocation within the instruction.
133 offset: u32,
134 /// Encoding of the instruction, used to determine how to modify it.
135 enc: Encoding.InstEnc,
136};
150137
151fn mirSystem(emit: *Emit, inst: Mir.Inst.Index) !void {
152 const tag = emit.mir.instructions.items(.tag)[inst];
138fn fixupRelocs(emit: *Emit) Error!void {
139 for (emit.relocs.items) |reloc| {
140 log.debug("target inst: {}", .{emit.lower.mir.instructions.get(reloc.target)});
141 const target = emit.code_offset_mapping.get(reloc.target) orelse
142 return emit.fail("relocation target not found!", .{});
153143
154 switch (tag) {
155 .ebreak => try emit.writeInstruction(Instruction.ebreak),
156 .ecall => try emit.writeInstruction(Instruction.ecall),
157 .unimp => try emit.writeInstruction(Instruction.unimp),
158 else => unreachable,
159 }
160}
144 const disp = @as(i32, @intCast(target)) - @as(i32, @intCast(reloc.source));
145 const code: *[4]u8 = emit.code.items[reloc.source + reloc.offset ..][0..4];
161146
162fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) !void {
163 const tag = emit.mir.instructions.items(.tag)[inst];
164 const dbg_line_column = emit.mir.instructions.items(.data)[inst].dbg_line_column;
147 log.debug("disp: {x}", .{disp});
165148
166 switch (tag) {
167 .dbg_line => try emit.dbgAdvancePCAndLine(dbg_line_column.line, dbg_line_column.column),
168 else => unreachable,
169 }
170}
171
172fn mirDebugPrologueEnd(self: *Emit) !void {
173 switch (self.debug_output) {
174 .dwarf => |dw| {
175 try dw.setPrologueEnd();
176 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
177 },
178 .plan9 => {},
179 .none => {},
149 switch (reloc.enc) {
150 .J => riscv_util.writeInstJ(code, @bitCast(disp)),
151 .B => riscv_util.writeInstB(code, @bitCast(disp)),
152 else => return emit.fail("tried to reloc encoding type {s}", .{@tagName(reloc.enc)}),
153 }
180154 }
181155}
182156
183fn mirDebugEpilogueBegin(self: *Emit) !void {
184 switch (self.debug_output) {
157fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
158 const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
159 const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
160 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
161 switch (emit.debug_output) {
185162 .dwarf => |dw| {
186 try dw.setEpilogueBegin();
187 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
163 if (column != emit.prev_di_column) try dw.setColumn(column);
164 if (delta_line == 0) return; // TODO: fix these edge cases.
165 try dw.advancePCAndLine(delta_line, delta_pc);
166 emit.prev_di_line = line;
167 emit.prev_di_column = column;
168 emit.prev_di_pc = emit.code.items.len;
188169 },
189170 .plan9 => {},
190171 .none => {},
191172 }
192173}
193174
194fn mirRR(emit: *Emit, inst: Mir.Inst.Index) !void {
195 const tag = emit.mir.instructions.items(.tag)[inst];
196 const rr = emit.mir.instructions.items(.data)[inst].rr;
197
198 switch (tag) {
199 .mv => try emit.writeInstruction(Instruction.addi(rr.rd, rr.rs, 0)),
200 else => unreachable,
201 }
202}
203fn mirUType(emit: *Emit, inst: Mir.Inst.Index) !void {
204 const tag = emit.mir.instructions.items(.tag)[inst];
205 const u_type = emit.mir.instructions.items(.data)[inst].u_type;
206
207 switch (tag) {
208 .lui => try emit.writeInstruction(Instruction.lui(u_type.rd, u_type.imm20)),
209 else => unreachable,
210 }
175fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error {
176 return switch (emit.lower.fail(format, args)) {
177 error.LowerFail => error.EmitFail,
178 else => |e| e,
179 };
211180}
212181
213fn mirNop(emit: *Emit, inst: Mir.Inst.Index) !void {
214 const tag = emit.mir.instructions.items(.tag)[inst];
182const link = @import("../../link.zig");
183const log = std.log.scoped(.emit);
184const mem = std.mem;
185const std = @import("std");
215186
216 switch (tag) {
217 .nop => try emit.writeInstruction(Instruction.addi(.zero, .zero, 0)),
218 .ret => try emit.writeInstruction(Instruction.jalr(.zero, 0, .ra)),
219 else => unreachable,
220 }
221}
187const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
188const Emit = @This();
189const Lower = @import("Lower.zig");
190const Mir = @import("Mir.zig");
191const riscv_util = @import("../../link/riscv.zig");
192const Encoding = @import("Encoding.zig");
193const Elf = @import("../../link/Elf.zig");
src/arch/riscv64/Encoding.zig created+403
......@@ -0,0 +1,403 @@
1mnemonic: Mnemonic,
2data: Data,
3
4pub const Mnemonic = enum {
5 // I Type
6 ld,
7 lw,
8 lwu,
9 lh,
10 lhu,
11 lb,
12 lbu,
13 sltiu,
14 xori,
15 andi,
16 slli,
17 srli,
18 srai,
19
20 addi,
21 jalr,
22
23 // U Type
24 lui,
25
26 // S Type
27 sd,
28 sw,
29 sh,
30 sb,
31
32 // J Type
33 jal,
34
35 // B Type
36 beq,
37
38 // R Type
39 add,
40 @"and",
41 sub,
42 slt,
43 mul,
44 sltu,
45 xor,
46
47 // System
48 ecall,
49 ebreak,
50 unimp,
51
52 pub fn encoding(mnem: Mnemonic) Enc {
53 return switch (mnem) {
54 // zig fmt: off
55 .add => .{ .opcode = 0b0110011, .funct3 = 0b000, .funct7 = 0b0000000 },
56 .sltu => .{ .opcode = 0b0110011, .funct3 = 0b011, .funct7 = 0b0000000 },
57 .@"and" => .{ .opcode = 0b0110011, .funct3 = 0b111, .funct7 = 0b0000000 },
58 .sub => .{ .opcode = 0b0110011, .funct3 = 0b000, .funct7 = 0b0100000 },
59
60 .ld => .{ .opcode = 0b0000011, .funct3 = 0b011, .funct7 = null },
61 .lw => .{ .opcode = 0b0000011, .funct3 = 0b010, .funct7 = null },
62 .lwu => .{ .opcode = 0b0000011, .funct3 = 0b110, .funct7 = null },
63 .lh => .{ .opcode = 0b0000011, .funct3 = 0b001, .funct7 = null },
64 .lhu => .{ .opcode = 0b0000011, .funct3 = 0b101, .funct7 = null },
65 .lb => .{ .opcode = 0b0000011, .funct3 = 0b000, .funct7 = null },
66 .lbu => .{ .opcode = 0b0000011, .funct3 = 0b100, .funct7 = null },
67
68 .sltiu => .{ .opcode = 0b0010011, .funct3 = 0b011, .funct7 = null },
69
70 .addi => .{ .opcode = 0b0010011, .funct3 = 0b000, .funct7 = null },
71 .andi => .{ .opcode = 0b0010011, .funct3 = 0b111, .funct7 = null },
72 .xori => .{ .opcode = 0b0010011, .funct3 = 0b100, .funct7 = null },
73 .jalr => .{ .opcode = 0b1100111, .funct3 = 0b000, .funct7 = null },
74 .slli => .{ .opcode = 0b0010011, .funct3 = 0b001, .funct7 = null },
75 .srli => .{ .opcode = 0b0010011, .funct3 = 0b101, .funct7 = null },
76 .srai => .{ .opcode = 0b0010011, .funct3 = 0b101, .funct7 = null, .offset = 1 << 10 },
77
78 .lui => .{ .opcode = 0b0110111, .funct3 = null, .funct7 = null },
79
80 .sd => .{ .opcode = 0b0100011, .funct3 = 0b011, .funct7 = null },
81 .sw => .{ .opcode = 0b0100011, .funct3 = 0b010, .funct7 = null },
82 .sh => .{ .opcode = 0b0100011, .funct3 = 0b001, .funct7 = null },
83 .sb => .{ .opcode = 0b0100011, .funct3 = 0b000, .funct7 = null },
84
85 .jal => .{ .opcode = 0b1101111, .funct3 = null, .funct7 = null },
86
87 .beq => .{ .opcode = 0b1100011, .funct3 = 0b000, .funct7 = null },
88
89 .slt => .{ .opcode = 0b0110011, .funct3 = 0b010, .funct7 = 0b0000000 },
90
91 .xor => .{ .opcode = 0b0110011, .funct3 = 0b100, .funct7 = 0b0000000 },
92
93 .mul => .{ .opcode = 0b0110011, .funct3 = 0b000, .funct7 = 0b0000001 },
94
95 .ecall => .{ .opcode = 0b1110011, .funct3 = 0b000, .funct7 = null },
96 .ebreak => .{ .opcode = 0b1110011, .funct3 = 0b000, .funct7 = null },
97 .unimp => .{ .opcode = 0b0000000, .funct3 = 0b000, .funct7 = null },
98 // zig fmt: on
99 };
100 }
101};
102
103pub const InstEnc = enum {
104 R,
105 I,
106 S,
107 B,
108 U,
109 J,
110
111 /// extras that have unusual op counts
112 system,
113
114 pub fn fromMnemonic(mnem: Mnemonic) InstEnc {
115 return switch (mnem) {
116 .addi,
117 .ld,
118 .lw,
119 .lwu,
120 .lh,
121 .lhu,
122 .lb,
123 .lbu,
124 .jalr,
125 .sltiu,
126 .xori,
127 .andi,
128 .slli,
129 .srli,
130 .srai,
131 => .I,
132
133 .lui,
134 => .U,
135
136 .sd,
137 .sw,
138 .sh,
139 .sb,
140 => .S,
141
142 .jal,
143 => .J,
144
145 .beq,
146 => .B,
147
148 .slt,
149 .sltu,
150 .mul,
151 .xor,
152 .add,
153 .sub,
154 .@"and",
155 => .R,
156
157 .ecall,
158 .ebreak,
159 .unimp,
160 => .system,
161 };
162 }
163
164 pub fn opsList(enc: InstEnc) [3]std.meta.FieldEnum(Operand) {
165 return switch (enc) {
166 // zig fmt: off
167 .R => .{ .reg, .reg, .reg, },
168 .I => .{ .reg, .reg, .imm, },
169 .S => .{ .reg, .reg, .imm, },
170 .B => .{ .reg, .reg, .imm, },
171 .U => .{ .reg, .imm, .none, },
172 .J => .{ .reg, .imm, .none, },
173 .system => .{ .none, .none, .none, },
174 // zig fmt: on
175 };
176 }
177};
178
179pub const Data = union(InstEnc) {
180 R: packed struct {
181 opcode: u7,
182 rd: u5,
183 funct3: u3,
184 rs1: u5,
185 rs2: u5,
186 funct7: u7,
187 },
188 I: packed struct {
189 opcode: u7,
190 rd: u5,
191 funct3: u3,
192 rs1: u5,
193 imm0_11: u12,
194 },
195 S: packed struct {
196 opcode: u7,
197 imm0_4: u5,
198 funct3: u3,
199 rs1: u5,
200 rs2: u5,
201 imm5_11: u7,
202 },
203 B: packed struct {
204 opcode: u7,
205 imm11: u1,
206 imm1_4: u4,
207 funct3: u3,
208 rs1: u5,
209 rs2: u5,
210 imm5_10: u6,
211 imm12: u1,
212 },
213 U: packed struct {
214 opcode: u7,
215 rd: u5,
216 imm12_31: u20,
217 },
218 J: packed struct {
219 opcode: u7,
220 rd: u5,
221 imm12_19: u8,
222 imm11: u1,
223 imm1_10: u10,
224 imm20: u1,
225 },
226 system: void,
227
228 pub fn toU32(self: Data) u32 {
229 return switch (self) {
230 .R => |v| @as(u32, @bitCast(v)),
231 .I => |v| @as(u32, @bitCast(v)),
232 .S => |v| @as(u32, @bitCast(v)),
233 .B => |v| @as(u32, @intCast(v.opcode)) + (@as(u32, @intCast(v.imm11)) << 7) + (@as(u32, @intCast(v.imm1_4)) << 8) + (@as(u32, @intCast(v.funct3)) << 12) + (@as(u32, @intCast(v.rs1)) << 15) + (@as(u32, @intCast(v.rs2)) << 20) + (@as(u32, @intCast(v.imm5_10)) << 25) + (@as(u32, @intCast(v.imm12)) << 31),
234 .U => |v| @as(u32, @bitCast(v)),
235 .J => |v| @as(u32, @bitCast(v)),
236 .system => unreachable,
237 };
238 }
239
240 pub fn construct(mnem: Mnemonic, ops: []const Operand) !Data {
241 const inst_enc = InstEnc.fromMnemonic(mnem);
242
243 const enc = mnem.encoding();
244
245 // special mnemonics
246 switch (mnem) {
247 .ecall,
248 .ebreak,
249 .unimp,
250 => {
251 assert(ops.len == 0);
252 return .{
253 .I = .{
254 .rd = Register.zero.id(),
255 .rs1 = Register.zero.id(),
256 .imm0_11 = switch (mnem) {
257 .ecall => 0x000,
258 .ebreak => 0x001,
259 .unimp => 0,
260 else => unreachable,
261 },
262
263 .opcode = enc.opcode,
264 .funct3 = enc.funct3.?,
265 },
266 };
267 },
268 else => {},
269 }
270
271 switch (inst_enc) {
272 .R => {
273 assert(ops.len == 3);
274 return .{
275 .R = .{
276 .rd = ops[0].reg.id(),
277 .rs1 = ops[1].reg.id(),
278 .rs2 = ops[2].reg.id(),
279
280 .opcode = enc.opcode,
281 .funct3 = enc.funct3.?,
282 .funct7 = enc.funct7.?,
283 },
284 };
285 },
286 .S => {
287 assert(ops.len == 3);
288 const umm = ops[2].imm.asBits(u12);
289
290 return .{
291 .S = .{
292 .imm0_4 = @truncate(umm),
293 .rs1 = ops[0].reg.id(),
294 .rs2 = ops[1].reg.id(),
295 .imm5_11 = @truncate(umm >> 5),
296
297 .opcode = enc.opcode,
298 .funct3 = enc.funct3.?,
299 },
300 };
301 },
302 .I => {
303 assert(ops.len == 3);
304 return .{
305 .I = .{
306 .rd = ops[0].reg.id(),
307 .rs1 = ops[1].reg.id(),
308 .imm0_11 = ops[2].imm.asBits(u12) + enc.offset,
309
310 .opcode = enc.opcode,
311 .funct3 = enc.funct3.?,
312 },
313 };
314 },
315 .U => {
316 assert(ops.len == 2);
317 return .{
318 .U = .{
319 .rd = ops[0].reg.id(),
320 .imm12_31 = ops[1].imm.asBits(u20),
321
322 .opcode = enc.opcode,
323 },
324 };
325 },
326 .J => {
327 assert(ops.len == 2);
328
329 const umm = ops[1].imm.asBits(u21);
330 assert(umm % 4 == 0); // misaligned jump target
331
332 return .{
333 .J = .{
334 .rd = ops[0].reg.id(),
335 .imm1_10 = @truncate(umm >> 1),
336 .imm11 = @truncate(umm >> 11),
337 .imm12_19 = @truncate(umm >> 12),
338 .imm20 = @truncate(umm >> 20),
339
340 .opcode = enc.opcode,
341 },
342 };
343 },
344 .B => {
345 assert(ops.len == 3);
346
347 const umm = ops[2].imm.asBits(u13);
348 assert(umm % 4 == 0); // misaligned branch target
349
350 return .{
351 .B = .{
352 .rs1 = ops[0].reg.id(),
353 .rs2 = ops[1].reg.id(),
354 .imm1_4 = @truncate(umm >> 1),
355 .imm5_10 = @truncate(umm >> 5),
356 .imm11 = @truncate(umm >> 11),
357 .imm12 = @truncate(umm >> 12),
358
359 .opcode = enc.opcode,
360 .funct3 = enc.funct3.?,
361 },
362 };
363 },
364
365 else => std.debug.panic("TODO: construct {s}", .{@tagName(inst_enc)}),
366 }
367 }
368};
369
370pub fn findByMnemonic(mnem: Mnemonic, ops: []const Operand) !?Encoding {
371 if (!verifyOps(mnem, ops)) return null;
372
373 return .{
374 .mnemonic = mnem,
375 .data = try Data.construct(mnem, ops),
376 };
377}
378
379const Enc = struct {
380 opcode: u7,
381 funct3: ?u3,
382 funct7: ?u7,
383 offset: u12 = 0,
384};
385
386fn verifyOps(mnem: Mnemonic, ops: []const Operand) bool {
387 const inst_enc = InstEnc.fromMnemonic(mnem);
388 const list = std.mem.sliceTo(&inst_enc.opsList(), .none);
389 for (list, ops) |l, o| if (l != std.meta.activeTag(o)) return false;
390 return true;
391}
392
393const std = @import("std");
394const assert = std.debug.assert;
395const log = std.log.scoped(.encoding);
396
397const Encoding = @This();
398const bits = @import("bits.zig");
399const Register = bits.Register;
400const encoder = @import("encoder.zig");
401const Instruction = encoder.Instruction;
402const Operand = Instruction.Operand;
403const OperandEnum = std.meta.FieldEnum(Operand);
src/arch/riscv64/Lower.zig created+360
......@@ -0,0 +1,360 @@
1//! This file contains the functionality for lowering RISC-V MIR to Instructions
2
3bin_file: *link.File,
4output_mode: std.builtin.OutputMode,
5link_mode: std.builtin.LinkMode,
6pic: bool,
7allocator: Allocator,
8mir: Mir,
9cc: std.builtin.CallingConvention,
10err_msg: ?*ErrorMsg = null,
11src_loc: Module.SrcLoc,
12result_insts_len: u8 = undefined,
13result_relocs_len: u8 = undefined,
14result_insts: [
15 @max(
16 1, // non-pseudo instruction
17 abi.callee_preserved_regs.len, // spill / restore regs,
18 )
19]Instruction = undefined,
20result_relocs: [1]Reloc = undefined,
21
22pub const Error = error{
23 OutOfMemory,
24 LowerFail,
25 InvalidInstruction,
26};
27
28pub const Reloc = struct {
29 lowered_inst_index: u8,
30 target: Target,
31
32 const Target = union(enum) {
33 inst: Mir.Inst.Index,
34
35 /// Relocs the lowered_inst_index and the next one.
36 load_symbol_reloc: bits.Symbol,
37 };
38};
39
40/// The returned slice is overwritten by the next call to lowerMir.
41pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
42 insts: []const Instruction,
43 relocs: []const Reloc,
44} {
45 lower.result_insts = undefined;
46 lower.result_relocs = undefined;
47 errdefer lower.result_insts = undefined;
48 errdefer lower.result_relocs = undefined;
49 lower.result_insts_len = 0;
50 lower.result_relocs_len = 0;
51 defer lower.result_insts_len = undefined;
52 defer lower.result_relocs_len = undefined;
53
54 const inst = lower.mir.instructions.get(index);
55 log.debug("lowerMir {}", .{inst});
56 switch (inst.tag) {
57 else => try lower.generic(inst),
58 .pseudo => switch (inst.ops) {
59 .pseudo_dbg_line_column,
60 .pseudo_dbg_epilogue_begin,
61 .pseudo_dbg_prologue_end,
62 .pseudo_dead,
63 => {},
64
65 .pseudo_load_rm, .pseudo_store_rm => {
66 const rm = inst.data.rm;
67
68 const frame_loc = rm.m.toFrameLoc(lower.mir);
69
70 switch (inst.ops) {
71 .pseudo_load_rm => {
72 const tag: Encoding.Mnemonic = switch (rm.m.mod.rm.size) {
73 .byte => .lb,
74 .hword => .lh,
75 .word => .lw,
76 .dword => .ld,
77 };
78
79 try lower.emit(tag, &.{
80 .{ .reg = rm.r },
81 .{ .reg = frame_loc.base },
82 .{ .imm = Immediate.s(frame_loc.disp) },
83 });
84 },
85 .pseudo_store_rm => {
86 const tag: Encoding.Mnemonic = switch (rm.m.mod.rm.size) {
87 .byte => .sb,
88 .hword => .sh,
89 .word => .sw,
90 .dword => .sd,
91 };
92
93 try lower.emit(tag, &.{
94 .{ .reg = frame_loc.base },
95 .{ .reg = rm.r },
96 .{ .imm = Immediate.s(frame_loc.disp) },
97 });
98 },
99 else => unreachable,
100 }
101 },
102
103 .pseudo_mv => {
104 const rr = inst.data.rr;
105
106 try lower.emit(.addi, &.{
107 .{ .reg = rr.rd },
108 .{ .reg = rr.rs },
109 .{ .imm = Immediate.s(0) },
110 });
111 },
112
113 .pseudo_ret => {
114 try lower.emit(.jalr, &.{
115 .{ .reg = .zero },
116 .{ .reg = .ra },
117 .{ .imm = Immediate.s(0) },
118 });
119 },
120
121 .pseudo_j => {
122 try lower.emit(.jal, &.{
123 .{ .reg = .zero },
124 .{ .imm = lower.reloc(.{ .inst = inst.data.inst }) },
125 });
126 },
127
128 .pseudo_spill_regs => try lower.pushPopRegList(true, inst.data.reg_list),
129 .pseudo_restore_regs => try lower.pushPopRegList(false, inst.data.reg_list),
130
131 .pseudo_load_symbol => {
132 const payload = inst.data.payload;
133 const data = lower.mir.extraData(Mir.LoadSymbolPayload, payload).data;
134
135 try lower.emit(.lui, &.{
136 .{ .reg = @enumFromInt(data.register) },
137 .{ .imm = lower.reloc(.{ .load_symbol_reloc = .{
138 .atom_index = data.atom_index,
139 .sym_index = data.sym_index,
140 } }) },
141 });
142
143 // the above reloc implies this one
144 try lower.emit(.addi, &.{
145 .{ .reg = @enumFromInt(data.register) },
146 .{ .reg = @enumFromInt(data.register) },
147 .{ .imm = Immediate.s(0) },
148 });
149 },
150
151 .pseudo_lea_rm => {
152 const rm = inst.data.rm;
153 const frame = rm.m.toFrameLoc(lower.mir);
154
155 try lower.emit(.addi, &.{
156 .{ .reg = rm.r },
157 .{ .reg = frame.base },
158 .{ .imm = Immediate.s(frame.disp) },
159 });
160 },
161
162 .pseudo_compare => {
163 const compare = inst.data.compare;
164 const op = compare.op;
165
166 const rd = compare.rd;
167 const rs1 = compare.rs1;
168 const rs2 = compare.rs2;
169
170 switch (op) {
171 .eq => {
172 try lower.emit(.xor, &.{
173 .{ .reg = rd },
174 .{ .reg = rs1 },
175 .{ .reg = rs2 },
176 });
177
178 try lower.emit(.sltiu, &.{
179 .{ .reg = rd },
180 .{ .reg = rd },
181 .{ .imm = Immediate.s(1) },
182 });
183 },
184 .neq => {
185 try lower.emit(.xor, &.{
186 .{ .reg = rd },
187 .{ .reg = rs1 },
188 .{ .reg = rs2 },
189 });
190
191 try lower.emit(.sltu, &.{
192 .{ .reg = rd },
193 .{ .reg = .zero },
194 .{ .reg = rd },
195 });
196 },
197 .gt => {
198 try lower.emit(.sltu, &.{
199 .{ .reg = rd },
200 .{ .reg = rs1 },
201 .{ .reg = rs2 },
202 });
203 },
204 .gte => {
205 try lower.emit(.sltu, &.{
206 .{ .reg = rd },
207 .{ .reg = rs1 },
208 .{ .reg = rs2 },
209 });
210
211 try lower.emit(.xori, &.{
212 .{ .reg = rd },
213 .{ .reg = rd },
214 .{ .imm = Immediate.s(1) },
215 });
216 },
217 .lt => {
218 try lower.emit(.slt, &.{
219 .{ .reg = rd },
220 .{ .reg = rs1 },
221 .{ .reg = rs2 },
222 });
223 },
224 .lte => {
225 try lower.emit(.slt, &.{
226 .{ .reg = rd },
227 .{ .reg = rs2 },
228 .{ .reg = rs1 },
229 });
230
231 try lower.emit(.xori, &.{
232 .{ .reg = rd },
233 .{ .reg = rd },
234 .{ .imm = Immediate.s(1) },
235 });
236 },
237 }
238 },
239
240 .pseudo_not => {
241 const rr = inst.data.rr;
242
243 try lower.emit(.xori, &.{
244 .{ .reg = rr.rd },
245 .{ .reg = rr.rs },
246 .{ .imm = Immediate.s(1) },
247 });
248 },
249
250 else => return lower.fail("TODO lower: psuedo {s}", .{@tagName(inst.ops)}),
251 },
252 }
253
254 return .{
255 .insts = lower.result_insts[0..lower.result_insts_len],
256 .relocs = lower.result_relocs[0..lower.result_relocs_len],
257 };
258}
259
260fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
261 const mnemonic = std.meta.stringToEnum(Encoding.Mnemonic, @tagName(inst.tag)) orelse {
262 return lower.fail("generic inst name '{s}' with op {s} doesn't match with a mnemonic", .{
263 @tagName(inst.tag),
264 @tagName(inst.ops),
265 });
266 };
267 try lower.emit(mnemonic, switch (inst.ops) {
268 .none => &.{},
269 .ri => &.{
270 .{ .reg = inst.data.u_type.rd },
271 .{ .imm = inst.data.u_type.imm20 },
272 },
273 .rr => &.{
274 .{ .reg = inst.data.rr.rd },
275 .{ .reg = inst.data.rr.rs },
276 },
277 .rri => &.{
278 .{ .reg = inst.data.i_type.rd },
279 .{ .reg = inst.data.i_type.rs1 },
280 .{ .imm = inst.data.i_type.imm12 },
281 },
282 .rr_inst => &.{
283 .{ .reg = inst.data.b_type.rs1 },
284 .{ .reg = inst.data.b_type.rs2 },
285 .{ .imm = lower.reloc(.{ .inst = inst.data.b_type.inst }) },
286 },
287 .rrr => &.{
288 .{ .reg = inst.data.r_type.rd },
289 .{ .reg = inst.data.r_type.rs1 },
290 .{ .reg = inst.data.r_type.rs2 },
291 },
292 else => return lower.fail("TODO: generic lower ops {s}", .{@tagName(inst.ops)}),
293 });
294}
295
296fn emit(lower: *Lower, mnemonic: Encoding.Mnemonic, ops: []const Instruction.Operand) !void {
297 lower.result_insts[lower.result_insts_len] =
298 try Instruction.new(mnemonic, ops);
299 lower.result_insts_len += 1;
300}
301
302fn reloc(lower: *Lower, target: Reloc.Target) Immediate {
303 lower.result_relocs[lower.result_relocs_len] = .{
304 .lowered_inst_index = lower.result_insts_len,
305 .target = target,
306 };
307 lower.result_relocs_len += 1;
308 return Immediate.s(0);
309}
310
311fn pushPopRegList(lower: *Lower, comptime spilling: bool, reg_list: Mir.RegisterList) !void {
312 var it = reg_list.iterator(.{ .direction = .forward });
313
314 var reg_i: u31 = 0;
315 while (it.next()) |i| {
316 const frame = lower.mir.frame_locs.get(@intFromEnum(bits.FrameIndex.spill_frame));
317
318 if (spilling) {
319 try lower.emit(.sd, &.{
320 .{ .reg = frame.base },
321 .{ .reg = abi.callee_preserved_regs[i] },
322 .{ .imm = Immediate.s(frame.disp + reg_i) },
323 });
324 } else {
325 try lower.emit(.ld, &.{
326 .{ .reg = abi.callee_preserved_regs[i] },
327 .{ .reg = frame.base },
328 .{ .imm = Immediate.s(frame.disp + reg_i) },
329 });
330 }
331
332 reg_i += 8;
333 }
334}
335
336pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
337 @setCold(true);
338 assert(lower.err_msg == null);
339 lower.err_msg = try ErrorMsg.create(lower.allocator, lower.src_loc, format, args);
340 return error.LowerFail;
341}
342
343const Lower = @This();
344
345const abi = @import("abi.zig");
346const assert = std.debug.assert;
347const bits = @import("bits.zig");
348const encoder = @import("encoder.zig");
349const link = @import("../../link.zig");
350const Encoding = @import("Encoding.zig");
351const std = @import("std");
352const log = std.log.scoped(.lower);
353
354const Air = @import("../../Air.zig");
355const Allocator = std.mem.Allocator;
356const ErrorMsg = Module.ErrorMsg;
357const Mir = @import("Mir.zig");
358const Module = @import("../../Module.zig");
359const Instruction = encoder.Instruction;
360const Immediate = bits.Immediate;
src/arch/riscv64/Mir.zig+307-56
......@@ -6,50 +6,111 @@
66//! The main purpose of MIR is to postpone the assignment of offsets until Isel,
77//! so that, for example, the smaller encodings of jump instructions can be used.
88
9const Mir = @This();
10const std = @import("std");
11const builtin = @import("builtin");
12const assert = std.debug.assert;
13
14const bits = @import("bits.zig");
15const Register = bits.Register;
16
179instructions: std.MultiArrayList(Inst).Slice,
1810/// The meaning of this data is determined by `Inst.Tag` value.
1911extra: []const u32,
12frame_locs: std.MultiArrayList(FrameLoc).Slice,
2013
2114pub const Inst = struct {
2215 tag: Tag,
23 /// The meaning of this depends on `tag`.
2416 data: Data,
17 ops: Ops,
18
19 /// The position of an MIR instruction within the `Mir` instructions array.
20 pub const Index = u32;
2521
2622 pub const Tag = enum(u16) {
27 add,
23 /// Add immediate. Uses i_type payload.
2824 addi,
29 /// Pseudo-instruction: End of prologue
30 dbg_prologue_end,
31 /// Pseudo-instruction: Beginning of epilogue
32 dbg_epilogue_begin,
33 /// Pseudo-instruction: Update debug line
34 dbg_line,
35 unimp,
36 ebreak,
37 ecall,
25
26 /// Add immediate and produce a sign-extended result.
27 ///
28 /// Uses i-type payload.
29 addiw,
30
3831 jalr,
39 ld,
4032 lui,
4133 mv,
34
35 @"and",
36 xor,
37
38 ebreak,
39 ecall,
40 unimp,
41
42 /// OR instruction. Uses r_type payload.
43 @"or",
44
45 /// Addition
46 add,
47 /// Subtraction
48 sub,
49 /// Multiply, uses r_type. Needs the M extension.
50 mul,
51
52 /// Absolute Value, uses i_type payload.
53 abs,
54
55 sltu,
56 slt,
57
58 /// Immediate Logical Right Shift, uses i_type payload
59 srli,
60 /// Immediate Logical Left Shift, uses i_type payload
61 slli,
62 /// Immediate Arithmetic Right Shift, uses i_type payload.
63 srai,
64 /// Register Logical Left Shift, uses r_type payload
65 sllw,
66 /// Register Logical Right Shit, uses r_type payload
67 srlw,
68
69 /// Jumps, but stores the address of the instruction following the
70 /// jump in `rd`.
71 ///
72 /// Uses j_type payload.
73 jal,
74
75 /// Immediate AND, uses i_type payload
76 andi,
77
78 /// Branch if equal, Uses b_type
79 beq,
80 /// Branch if not equal, Uses b_type
81 bne,
82
83 /// Boolean NOT, Uses rr payload
84 not,
85
86 /// Generates a NO-OP, uses nop payload
4287 nop,
43 ret,
88
89 /// Load double (64 bits), uses i_type payload
90 ld,
91 /// Load word (32 bits), uses i_type payload
92 lw,
93 /// Load half (16 bits), uses i_type payload
94 lh,
95 /// Load byte (8 bits), uses i_type payload
96 lb,
97
98 /// Store double (64 bits), uses s_type payload
4499 sd,
45 sub,
46 };
100 /// Store word (32 bits), uses s_type payload
101 sw,
102 /// Store half (16 bits), uses s_type payload
103 sh,
104 /// Store byte (8 bits), uses s_type payload
105 sb,
47106
48 /// The position of an MIR instruction within the `Mir` instructions array.
49 pub const Index = u32;
107 /// A pseudo-instruction. Used for anything that isn't 1:1 with an
108 /// assembly instruction.
109 pseudo,
110 };
50111
51112 /// All instructions have a 4-byte payload, which is contained within
52 /// this union. `Tag` determines which union field is active, as well as
113 /// this union. `Ops` determines which union field is active, as well as
53114 /// how to interpret the data within.
54115 pub const Data = union {
55116 /// No additional data
......@@ -60,72 +121,206 @@ pub const Inst = struct {
60121 ///
61122 /// Used by e.g. b
62123 inst: Index,
63 /// A 16-bit immediate value.
64 ///
65 /// Used by e.g. svc
66 imm16: u16,
67124 /// Index into `extra`. Meaning of what can be found there is context-dependent.
68125 ///
69126 /// Used by e.g. load_memory
70127 payload: u32,
71 /// A register
72 ///
73 /// Used by e.g. blr
74 reg: Register,
75 /// Two registers
76 ///
77 /// Used by e.g. mv
78 rr: struct {
128
129 r_type: struct {
79130 rd: Register,
80 rs: Register,
131 rs1: Register,
132 rs2: Register,
81133 },
82 /// I-Type
83 ///
84 /// Used by e.g. jalr
134
85135 i_type: struct {
86136 rd: Register,
87137 rs1: Register,
88 imm12: i12,
138 imm12: Immediate,
89139 },
90 /// R-Type
91 ///
92 /// Used by e.g. add
93 r_type: struct {
94 rd: Register,
140
141 s_type: struct {
95142 rs1: Register,
96143 rs2: Register,
144 imm5: Immediate,
145 imm7: Immediate,
97146 },
98 /// U-Type
99 ///
100 /// Used by e.g. lui
147
148 b_type: struct {
149 rs1: Register,
150 rs2: Register,
151 inst: Inst.Index,
152 },
153
101154 u_type: struct {
102155 rd: Register,
103 imm20: i20,
156 imm20: Immediate,
157 },
158
159 j_type: struct {
160 rd: Register,
161 inst: Inst.Index,
104162 },
163
105164 /// Debug info: line and column
106165 ///
107 /// Used by e.g. dbg_line
108 dbg_line_column: struct {
166 /// Used by e.g. pseudo_dbg_line
167 pseudo_dbg_line_column: struct {
109168 line: u32,
110169 column: u32,
111170 },
171
172 // Custom types to be lowered
173
174 /// Register + Memory
175 rm: struct {
176 r: Register,
177 m: Memory,
178 },
179
180 reg_list: Mir.RegisterList,
181
182 /// A register
183 ///
184 /// Used by e.g. blr
185 reg: Register,
186
187 /// Two registers
188 ///
189 /// Used by e.g. mv
190 rr: struct {
191 rd: Register,
192 rs: Register,
193 },
194
195 compare: struct {
196 rd: Register,
197 rs1: Register,
198 rs2: Register,
199 op: enum {
200 eq,
201 neq,
202 gt,
203 gte,
204 lt,
205 lte,
206 },
207 },
208 };
209
210 pub const Ops = enum {
211 /// No data associated with this instruction (only mnemonic is used).
212 none,
213 /// Two registers
214 rr,
215 /// Three registers
216 rrr,
217
218 /// Two registers + immediate, uses the i_type payload.
219 rri,
220 /// Two registers + Two Immediates
221 rrii,
222
223 /// Two registers + another instruction.
224 rr_inst,
225
226 /// Register + Memory
227 rm,
228
229 /// Register + Immediate
230 ri,
231
232 /// Another instruction.
233 inst,
234
235 /// Pseudo-instruction that will generate a backpatched
236 /// function prologue.
237 pseudo_prologue,
238 /// Pseudo-instruction that will generate a backpatched
239 /// function epilogue
240 pseudo_epilogue,
241
242 /// Pseudo-instruction: End of prologue
243 pseudo_dbg_prologue_end,
244 /// Pseudo-instruction: Beginning of epilogue
245 pseudo_dbg_epilogue_begin,
246 /// Pseudo-instruction: Update debug line
247 pseudo_dbg_line_column,
248
249 /// Pseudo-instruction that loads from memory into a register.
250 ///
251 /// Uses `rm` payload.
252 pseudo_load_rm,
253 /// Pseudo-instruction that stores from a register into memory
254 ///
255 /// Uses `rm` payload.
256 pseudo_store_rm,
257
258 /// Pseudo-instruction that loads the address of memory into a register.
259 ///
260 /// Uses `rm` payload.
261 pseudo_lea_rm,
262
263 /// Shorthand for returning, aka jumping to ra register.
264 ///
265 /// Uses nop payload.
266 pseudo_ret,
267
268 /// Jumps. Uses `inst` payload.
269 pseudo_j,
270
271 /// Dead inst, ignored by the emitter.
272 pseudo_dead,
273
274 /// Loads the address of a value that hasn't yet been allocated in memory.
275 ///
276 /// uses the Mir.LoadSymbolPayload payload.
277 pseudo_load_symbol,
278
279 /// Moves the value of rs1 to rd.
280 ///
281 /// uses the `rr` payload.
282 pseudo_mv,
283
284 pseudo_restore_regs,
285 pseudo_spill_regs,
286
287 pseudo_compare,
288 pseudo_not,
112289 };
113290
114291 // Make sure we don't accidentally make instructions bigger than expected.
115 // Note that in safety builds, Zig is allowed to insert a secret field for safety checks.
292 // Note that in Debug builds, Zig is allowed to insert a secret field for safety checks.
116293 // comptime {
117 // if (!std.debug.runtime_safety) {
294 // if (builtin.mode != .Debug) {
118295 // assert(@sizeOf(Inst) == 8);
119296 // }
120297 // }
298
299 pub fn format(
300 inst: Inst,
301 comptime fmt: []const u8,
302 options: std.fmt.FormatOptions,
303 writer: anytype,
304 ) !void {
305 assert(fmt.len == 0);
306 _ = options;
307
308 try writer.print("Tag: {s}, Ops: {s}", .{ @tagName(inst.tag), @tagName(inst.ops) });
309 }
121310};
122311
123312pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
124313 mir.instructions.deinit(gpa);
314 mir.frame_locs.deinit(gpa);
125315 gpa.free(mir.extra);
126316 mir.* = undefined;
127317}
128318
319pub const FrameLoc = struct {
320 base: Register,
321 disp: i32,
322};
323
129324/// Returns the requested data, as well as the new index which is at the start of the
130325/// trailers for the object.
131326pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
......@@ -145,3 +340,59 @@ pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end
145340 .end = i,
146341 };
147342}
343
344pub const LoadSymbolPayload = struct {
345 register: u32,
346 atom_index: u32,
347 sym_index: u32,
348};
349
350/// Used in conjunction with payload to transfer a list of used registers in a compact manner.
351pub const RegisterList = struct {
352 bitset: BitSet = BitSet.initEmpty(),
353
354 const BitSet = IntegerBitSet(32);
355 const Self = @This();
356
357 fn getIndexForReg(registers: []const Register, reg: Register) BitSet.MaskInt {
358 for (registers, 0..) |cpreg, i| {
359 if (reg.id() == cpreg.id()) return @intCast(i);
360 }
361 unreachable; // register not in input register list!
362 }
363
364 pub fn push(self: *Self, registers: []const Register, reg: Register) void {
365 const index = getIndexForReg(registers, reg);
366 self.bitset.set(index);
367 }
368
369 pub fn isSet(self: Self, registers: []const Register, reg: Register) bool {
370 const index = getIndexForReg(registers, reg);
371 return self.bitset.isSet(index);
372 }
373
374 pub fn iterator(self: Self, comptime options: std.bit_set.IteratorOptions) BitSet.Iterator(options) {
375 return self.bitset.iterator(options);
376 }
377
378 pub fn count(self: Self) i32 {
379 return @intCast(self.bitset.count());
380 }
381
382 pub fn size(self: Self) i32 {
383 return @intCast(self.bitset.count() * 8);
384 }
385};
386
387const Mir = @This();
388const std = @import("std");
389const builtin = @import("builtin");
390const assert = std.debug.assert;
391
392const bits = @import("bits.zig");
393const Register = bits.Register;
394const Immediate = bits.Immediate;
395const Memory = bits.Memory;
396const FrameIndex = bits.FrameIndex;
397const FrameAddr = @import("CodeGen.zig").FrameAddr;
398const IntegerBitSet = std.bit_set.IntegerBitSet;
src/arch/riscv64/abi.zig+182-3
......@@ -3,9 +3,11 @@ const bits = @import("bits.zig");
33const Register = bits.Register;
44const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
55const Type = @import("../../type.zig").Type;
6const InternPool = @import("../../InternPool.zig");
67const Module = @import("../../Module.zig");
8const assert = std.debug.assert;
79
8pub const Class = enum { memory, byval, integer, double_integer, fields };
10pub const Class = enum { memory, byval, integer, double_integer, fields, none };
911
1012pub fn classifyType(ty: Type, mod: *Module) Class {
1113 const target = mod.getTarget();
......@@ -91,11 +93,161 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
9193 }
9294}
9395
96/// There are a maximum of 8 possible return slots. Returned values are in
97/// the beginning of the array; unused slots are filled with .none.
98pub fn classifySystem(ty: Type, zcu: *Module) [8]Class {
99 var result = [1]Class{.none} ** 8;
100 const memory_class = [_]Class{
101 .memory, .none, .none, .none,
102 .none, .none, .none, .none,
103 };
104 switch (ty.zigTypeTag(zcu)) {
105 .Bool, .Void, .NoReturn => {
106 result[0] = .integer;
107 return result;
108 },
109 .Pointer => switch (ty.ptrSize(zcu)) {
110 .Slice => {
111 result[0] = .integer;
112 result[1] = .integer;
113 return result;
114 },
115 else => {
116 result[0] = .integer;
117 return result;
118 },
119 },
120 .Optional => {
121 if (ty.isPtrLikeOptional(zcu)) {
122 result[0] = .integer;
123 return result;
124 }
125 result[0] = .integer;
126 result[1] = .integer;
127 return result;
128 },
129 .Int, .Enum, .ErrorSet => {
130 const int_bits = ty.intInfo(zcu).bits;
131 if (int_bits <= 64) {
132 result[0] = .integer;
133 return result;
134 }
135 if (int_bits <= 128) {
136 result[0] = .integer;
137 result[1] = .integer;
138 return result;
139 }
140 unreachable; // support > 128 bit int arguments
141 },
142 .ErrorUnion => {
143 const payload_ty = ty.errorUnionPayload(zcu);
144 const payload_bits = payload_ty.bitSize(zcu);
145
146 // the error union itself
147 result[0] = .integer;
148
149 // anyerror!void can fit into one register
150 if (payload_bits == 0) return result;
151
152 if (payload_bits <= 64) {
153 result[1] = .integer;
154 return result;
155 }
156
157 std.debug.panic("TODO: classifySystem ErrorUnion > 64 bit payload", .{});
158 },
159 .Struct => {
160 const layout = ty.containerLayout(zcu);
161 const ty_size = ty.abiSize(zcu);
162
163 if (layout == .@"packed") {
164 assert(ty_size <= 16);
165 result[0] = .integer;
166 if (ty_size > 8) result[1] = .integer;
167 return result;
168 }
169
170 return memory_class;
171 },
172 else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),
173 }
174}
175
176fn classifyStruct(
177 result: *[8]Class,
178 byte_offset: *u64,
179 loaded_struct: InternPool.LoadedStructType,
180 zcu: *Module,
181) void {
182 const ip = &zcu.intern_pool;
183 var field_it = loaded_struct.iterateRuntimeOrder(ip);
184
185 while (field_it.next()) |field_index| {
186 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
187 const field_align = loaded_struct.fieldAlign(ip, field_index);
188 byte_offset.* = std.mem.alignForward(
189 u64,
190 byte_offset.*,
191 field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?,
192 );
193 if (zcu.typeToStruct(field_ty)) |field_loaded_struct| {
194 if (field_loaded_struct.layout != .@"packed") {
195 classifyStruct(result, byte_offset, field_loaded_struct, zcu);
196 continue;
197 }
198 }
199 const field_class = std.mem.sliceTo(&classifySystem(field_ty, zcu), .none);
200 const field_size = field_ty.abiSize(zcu);
201
202 combine: {
203 const result_class = &result[@intCast(byte_offset.* / 8)];
204 if (result_class.* == field_class[0]) {
205 break :combine;
206 }
207
208 if (result_class.* == .none) {
209 result_class.* = field_class[0];
210 break :combine;
211 }
212 assert(field_class[0] != .none);
213
214 // "If one of the classes is MEMORY, the result is the MEMORY class."
215 if (result_class.* == .memory or field_class[0] == .memory) {
216 result_class.* = .memory;
217 break :combine;
218 }
219
220 // "If one of the classes is INTEGER, the result is the INTEGER."
221 if (result_class.* == .integer or field_class[0] == .integer) {
222 result_class.* = .integer;
223 break :combine;
224 }
225
226 result_class.* = .integer;
227 }
228 @memcpy(result[@intCast(byte_offset.* / 8 + 1)..][0 .. field_class.len - 1], field_class[1..]);
229 byte_offset.* += field_size;
230 }
231}
232
94233pub const callee_preserved_regs = [_]Register{
95 .s0, .s1, .s2, .s3, .s4, .s5, .s6, .s7, .s8, .s9, .s10, .s11,
234 // .s0 is ommited to be used as a frame pointer
235 .s1, .s2, .s3, .s4, .s5, .s6, .s7, .s8, .s9, .s10, .s11,
236};
237
238pub const function_arg_regs = [_]Register{
239 .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7,
240};
241
242pub const function_ret_regs = [_]Register{
243 .a0, .a1,
244};
245
246pub const temporary_regs = [_]Register{
247 .t0, .t1, .t2, .t3, .t4, .t5, .t6,
96248};
97249
98const allocatable_registers = callee_preserved_regs;
250const allocatable_registers = callee_preserved_regs ++ function_arg_regs ++ temporary_regs;
99251pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, &allocatable_registers);
100252
101253// Register classes
......@@ -109,4 +261,31 @@ pub const RegisterClass = struct {
109261 }, true);
110262 break :blk set;
111263 };
264
265 pub const fa: RegisterBitSet = blk: {
266 var set = RegisterBitSet.initEmpty();
267 set.setRangeValue(.{
268 .start = callee_preserved_regs.len,
269 .end = callee_preserved_regs.len + function_arg_regs.len,
270 }, true);
271 break :blk set;
272 };
273
274 pub const fr: RegisterBitSet = blk: {
275 var set = RegisterBitSet.initEmpty();
276 set.setRangeValue(.{
277 .start = callee_preserved_regs.len,
278 .end = callee_preserved_regs.len + function_ret_regs.len,
279 }, true);
280 break :blk set;
281 };
282
283 pub const tp: RegisterBitSet = blk: {
284 var set = RegisterBitSet.initEmpty();
285 set.setRangeValue(.{
286 .start = callee_preserved_regs.len + function_arg_regs.len,
287 .end = callee_preserved_regs.len + function_arg_regs.len + temporary_regs.len,
288 }, true);
289 break :blk set;
290 };
112291};
src/arch/riscv64/bits.zig+170-393
......@@ -2,385 +2,149 @@ const std = @import("std");
22const DW = std.dwarf;
33const assert = std.debug.assert;
44const testing = std.testing;
5const Encoding = @import("Encoding.zig");
6const Mir = @import("Mir.zig");
57
6// TODO: this is only tagged to facilitate the monstrosity.
7// Once packed structs work make it packed.
8pub const Instruction = union(enum) {
9 R: packed struct {
10 opcode: u7,
11 rd: u5,
12 funct3: u3,
13 rs1: u5,
14 rs2: u5,
15 funct7: u7,
16 },
17 I: packed struct {
18 opcode: u7,
19 rd: u5,
20 funct3: u3,
21 rs1: u5,
22 imm0_11: u12,
23 },
24 S: packed struct {
25 opcode: u7,
26 imm0_4: u5,
27 funct3: u3,
28 rs1: u5,
29 rs2: u5,
30 imm5_11: u7,
31 },
32 B: packed struct {
33 opcode: u7,
34 imm11: u1,
35 imm1_4: u4,
36 funct3: u3,
37 rs1: u5,
38 rs2: u5,
39 imm5_10: u6,
40 imm12: u1,
41 },
42 U: packed struct {
43 opcode: u7,
44 rd: u5,
45 imm12_31: u20,
46 },
47 J: packed struct {
48 opcode: u7,
49 rd: u5,
50 imm12_19: u8,
51 imm11: u1,
52 imm1_10: u10,
53 imm20: u1,
54 },
8pub const Memory = struct {
9 base: Base,
10 mod: Mod,
5511
56 // TODO: once packed structs work we can remove this monstrosity.
57 pub fn toU32(self: Instruction) u32 {
58 return switch (self) {
59 .R => |v| @as(u32, @bitCast(v)),
60 .I => |v| @as(u32, @bitCast(v)),
61 .S => |v| @as(u32, @bitCast(v)),
62 .B => |v| @as(u32, @intCast(v.opcode)) + (@as(u32, @intCast(v.imm11)) << 7) + (@as(u32, @intCast(v.imm1_4)) << 8) + (@as(u32, @intCast(v.funct3)) << 12) + (@as(u32, @intCast(v.rs1)) << 15) + (@as(u32, @intCast(v.rs2)) << 20) + (@as(u32, @intCast(v.imm5_10)) << 25) + (@as(u32, @intCast(v.imm12)) << 31),
63 .U => |v| @as(u32, @bitCast(v)),
64 .J => |v| @as(u32, @bitCast(v)),
65 };
66 }
12 pub const Base = union(enum) {
13 reg: Register,
14 frame: FrameIndex,
15 reloc: Symbol,
16 };
6717
68 fn rType(op: u7, fn3: u3, fn7: u7, rd: Register, r1: Register, r2: Register) Instruction {
69 return Instruction{
70 .R = .{
71 .opcode = op,
72 .funct3 = fn3,
73 .funct7 = fn7,
74 .rd = rd.id(),
75 .rs1 = r1.id(),
76 .rs2 = r2.id(),
77 },
78 };
79 }
18 pub const Mod = union(enum(u1)) {
19 rm: struct {
20 size: Size,
21 disp: i32 = 0,
22 },
23 off: i32,
24 };
8025
81 // RISC-V is all signed all the time -- convert immediates to unsigned for processing
82 fn iType(op: u7, fn3: u3, rd: Register, r1: Register, imm: i12) Instruction {
83 const umm = @as(u12, @bitCast(imm));
26 pub const Size = enum(u4) {
27 /// Byte, 1 byte
28 byte,
29 /// Half word, 2 bytes
30 hword,
31 /// Word, 4 bytes
32 word,
33 /// Double word, 8 Bytes
34 dword,
35
36 pub fn fromByteSize(size: u64) Size {
37 return switch (size) {
38 1 => .byte,
39 2 => .hword,
40 4 => .word,
41 8 => .dword,
42 else => unreachable,
43 };
44 }
45
46 pub fn fromBitSize(bit_size: u64) Size {
47 return switch (bit_size) {
48 8 => .byte,
49 16 => .hword,
50 32 => .word,
51 64 => .dword,
52 else => unreachable,
53 };
54 }
55
56 pub fn bitSize(s: Size) u64 {
57 return switch (s) {
58 .byte => 8,
59 .hword => 16,
60 .word => 32,
61 .dword => 64,
62 };
63 }
64 };
8465
85 return Instruction{
86 .I = .{
87 .opcode = op,
88 .funct3 = fn3,
89 .rd = rd.id(),
90 .rs1 = r1.id(),
91 .imm0_11 = umm,
92 },
66 /// Asserts `mem` can be represented as a `FrameLoc`.
67 pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {
68 const offset: i32 = switch (mem.mod) {
69 .off => |off| off,
70 .rm => |rm| rm.disp,
9371 };
94 }
95
96 fn sType(op: u7, fn3: u3, r1: Register, r2: Register, imm: i12) Instruction {
97 const umm = @as(u12, @bitCast(imm));
9872
99 return Instruction{
100 .S = .{
101 .opcode = op,
102 .funct3 = fn3,
103 .rs1 = r1.id(),
104 .rs2 = r2.id(),
105 .imm0_4 = @as(u5, @truncate(umm)),
106 .imm5_11 = @as(u7, @truncate(umm >> 5)),
73 switch (mem.base) {
74 .reg => |reg| {
75 return .{
76 .base = reg,
77 .disp = offset,
78 };
10779 },
108 };
80 .frame => |index| {
81 const base_loc = mir.frame_locs.get(@intFromEnum(index));
82 return .{
83 .base = base_loc.base,
84 .disp = base_loc.disp + offset,
85 };
86 },
87 .reloc => unreachable,
88 }
10989 }
90};
11091
111 // Use significance value rather than bit value, same for J-type
112 // -- less burden on callsite, bonus semantic checking
113 fn bType(op: u7, fn3: u3, r1: Register, r2: Register, imm: i13) Instruction {
114 const umm = @as(u13, @bitCast(imm));
115 assert(umm % 2 == 0); // misaligned branch target
92pub const Immediate = union(enum) {
93 signed: i32,
94 unsigned: u32,
11695
117 return Instruction{
118 .B = .{
119 .opcode = op,
120 .funct3 = fn3,
121 .rs1 = r1.id(),
122 .rs2 = r2.id(),
123 .imm1_4 = @as(u4, @truncate(umm >> 1)),
124 .imm5_10 = @as(u6, @truncate(umm >> 5)),
125 .imm11 = @as(u1, @truncate(umm >> 11)),
126 .imm12 = @as(u1, @truncate(umm >> 12)),
127 },
128 };
96 pub fn u(x: u64) Immediate {
97 return .{ .unsigned = x };
12998 }
13099
131 // We have to extract the 20 bits anyway -- let's not make it more painful
132 fn uType(op: u7, rd: Register, imm: i20) Instruction {
133 const umm = @as(u20, @bitCast(imm));
100 pub fn s(x: i32) Immediate {
101 return .{ .signed = x };
102 }
134103
135 return Instruction{
136 .U = .{
137 .opcode = op,
138 .rd = rd.id(),
139 .imm12_31 = umm,
104 pub fn asSigned(imm: Immediate, bit_size: u64) i64 {
105 return switch (imm) {
106 .signed => |x| switch (bit_size) {
107 1, 8 => @as(i8, @intCast(x)),
108 16 => @as(i16, @intCast(x)),
109 32, 64 => x,
110 else => unreachable,
111 },
112 .unsigned => |x| switch (bit_size) {
113 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))),
114 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))),
115 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))),
116 64 => @bitCast(x),
117 else => unreachable,
140118 },
141119 };
142120 }
143121
144 fn jType(op: u7, rd: Register, imm: i21) Instruction {
145 const umm = @as(u21, @bitCast(imm));
146 assert(umm % 2 == 0); // misaligned jump target
147
148 return Instruction{
149 .J = .{
150 .opcode = op,
151 .rd = rd.id(),
152 .imm1_10 = @as(u10, @truncate(umm >> 1)),
153 .imm11 = @as(u1, @truncate(umm >> 11)),
154 .imm12_19 = @as(u8, @truncate(umm >> 12)),
155 .imm20 = @as(u1, @truncate(umm >> 20)),
122 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {
123 return switch (imm) {
124 .signed => |x| switch (bit_size) {
125 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))),
126 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))),
127 32, 64 => @as(u32, @bitCast(x)),
128 else => unreachable,
129 },
130 .unsigned => |x| switch (bit_size) {
131 1, 8 => @as(u8, @intCast(x)),
132 16 => @as(u16, @intCast(x)),
133 32 => @as(u32, @intCast(x)),
134 64 => x,
135 else => unreachable,
156136 },
157137 };
158138 }
159139
160 // The meat and potatoes. Arguments are in the order in which they would appear in assembly code.
161
162 // Arithmetic/Logical, Register-Register
163
164 pub fn add(rd: Register, r1: Register, r2: Register) Instruction {
165 return rType(0b0110011, 0b000, 0b0000000, rd, r1, r2);
166 }
167
168 pub fn sub(rd: Register, r1: Register, r2: Register) Instruction {
169 return rType(0b0110011, 0b000, 0b0100000, rd, r1, r2);
170 }
171
172 pub fn @"and"(rd: Register, r1: Register, r2: Register) Instruction {
173 return rType(0b0110011, 0b111, 0b0000000, rd, r1, r2);
174 }
175
176 pub fn @"or"(rd: Register, r1: Register, r2: Register) Instruction {
177 return rType(0b0110011, 0b110, 0b0000000, rd, r1, r2);
178 }
179
180 pub fn xor(rd: Register, r1: Register, r2: Register) Instruction {
181 return rType(0b0110011, 0b100, 0b0000000, rd, r1, r2);
182 }
183
184 pub fn sll(rd: Register, r1: Register, r2: Register) Instruction {
185 return rType(0b0110011, 0b001, 0b0000000, rd, r1, r2);
186 }
187
188 pub fn srl(rd: Register, r1: Register, r2: Register) Instruction {
189 return rType(0b0110011, 0b101, 0b0000000, rd, r1, r2);
190 }
191
192 pub fn sra(rd: Register, r1: Register, r2: Register) Instruction {
193 return rType(0b0110011, 0b101, 0b0100000, rd, r1, r2);
194 }
195
196 pub fn slt(rd: Register, r1: Register, r2: Register) Instruction {
197 return rType(0b0110011, 0b010, 0b0000000, rd, r1, r2);
198 }
199
200 pub fn sltu(rd: Register, r1: Register, r2: Register) Instruction {
201 return rType(0b0110011, 0b011, 0b0000000, rd, r1, r2);
202 }
203
204 // Arithmetic/Logical, Register-Register (32-bit)
205
206 pub fn addw(rd: Register, r1: Register, r2: Register) Instruction {
207 return rType(0b0111011, 0b000, rd, r1, r2);
208 }
209
210 pub fn subw(rd: Register, r1: Register, r2: Register) Instruction {
211 return rType(0b0111011, 0b000, 0b0100000, rd, r1, r2);
212 }
213
214 pub fn sllw(rd: Register, r1: Register, r2: Register) Instruction {
215 return rType(0b0111011, 0b001, 0b0000000, rd, r1, r2);
216 }
217
218 pub fn srlw(rd: Register, r1: Register, r2: Register) Instruction {
219 return rType(0b0111011, 0b101, 0b0000000, rd, r1, r2);
220 }
221
222 pub fn sraw(rd: Register, r1: Register, r2: Register) Instruction {
223 return rType(0b0111011, 0b101, 0b0100000, rd, r1, r2);
224 }
225
226 // Arithmetic/Logical, Register-Immediate
227
228 pub fn addi(rd: Register, r1: Register, imm: i12) Instruction {
229 return iType(0b0010011, 0b000, rd, r1, imm);
230 }
231
232 pub fn andi(rd: Register, r1: Register, imm: i12) Instruction {
233 return iType(0b0010011, 0b111, rd, r1, imm);
234 }
235
236 pub fn ori(rd: Register, r1: Register, imm: i12) Instruction {
237 return iType(0b0010011, 0b110, rd, r1, imm);
238 }
239
240 pub fn xori(rd: Register, r1: Register, imm: i12) Instruction {
241 return iType(0b0010011, 0b100, rd, r1, imm);
242 }
243
244 pub fn slli(rd: Register, r1: Register, shamt: u6) Instruction {
245 return iType(0b0010011, 0b001, rd, r1, shamt);
246 }
247
248 pub fn srli(rd: Register, r1: Register, shamt: u6) Instruction {
249 return iType(0b0010011, 0b101, rd, r1, shamt);
250 }
251
252 pub fn srai(rd: Register, r1: Register, shamt: u6) Instruction {
253 return iType(0b0010011, 0b101, rd, r1, (1 << 10) + shamt);
254 }
255
256 pub fn slti(rd: Register, r1: Register, imm: i12) Instruction {
257 return iType(0b0010011, 0b010, rd, r1, imm);
258 }
259
260 pub fn sltiu(rd: Register, r1: Register, imm: u12) Instruction {
261 return iType(0b0010011, 0b011, rd, r1, @as(i12, @bitCast(imm)));
262 }
263
264 // Arithmetic/Logical, Register-Immediate (32-bit)
265
266 pub fn addiw(rd: Register, r1: Register, imm: i12) Instruction {
267 return iType(0b0011011, 0b000, rd, r1, imm);
268 }
269
270 pub fn slliw(rd: Register, r1: Register, shamt: u5) Instruction {
271 return iType(0b0011011, 0b001, rd, r1, shamt);
272 }
273
274 pub fn srliw(rd: Register, r1: Register, shamt: u5) Instruction {
275 return iType(0b0011011, 0b101, rd, r1, shamt);
276 }
277
278 pub fn sraiw(rd: Register, r1: Register, shamt: u5) Instruction {
279 return iType(0b0011011, 0b101, rd, r1, (1 << 10) + shamt);
280 }
281
282 // Upper Immediate
283
284 pub fn lui(rd: Register, imm: i20) Instruction {
285 return uType(0b0110111, rd, imm);
286 }
287
288 pub fn auipc(rd: Register, imm: i20) Instruction {
289 return uType(0b0010111, rd, imm);
290 }
291
292 // Load
293
294 pub fn ld(rd: Register, offset: i12, base: Register) Instruction {
295 return iType(0b0000011, 0b011, rd, base, offset);
296 }
297
298 pub fn lw(rd: Register, offset: i12, base: Register) Instruction {
299 return iType(0b0000011, 0b010, rd, base, offset);
300 }
301
302 pub fn lwu(rd: Register, offset: i12, base: Register) Instruction {
303 return iType(0b0000011, 0b110, rd, base, offset);
304 }
305
306 pub fn lh(rd: Register, offset: i12, base: Register) Instruction {
307 return iType(0b0000011, 0b001, rd, base, offset);
308 }
309
310 pub fn lhu(rd: Register, offset: i12, base: Register) Instruction {
311 return iType(0b0000011, 0b101, rd, base, offset);
312 }
313
314 pub fn lb(rd: Register, offset: i12, base: Register) Instruction {
315 return iType(0b0000011, 0b000, rd, base, offset);
316 }
317
318 pub fn lbu(rd: Register, offset: i12, base: Register) Instruction {
319 return iType(0b0000011, 0b100, rd, base, offset);
320 }
321
322 // Store
323
324 pub fn sd(rs: Register, offset: i12, base: Register) Instruction {
325 return sType(0b0100011, 0b011, base, rs, offset);
326 }
327
328 pub fn sw(rs: Register, offset: i12, base: Register) Instruction {
329 return sType(0b0100011, 0b010, base, rs, offset);
330 }
331
332 pub fn sh(rs: Register, offset: i12, base: Register) Instruction {
333 return sType(0b0100011, 0b001, base, rs, offset);
334 }
335
336 pub fn sb(rs: Register, offset: i12, base: Register) Instruction {
337 return sType(0b0100011, 0b000, base, rs, offset);
338 }
339
340 // Fence
341 // TODO: implement fence
342
343 // Branch
344
345 pub fn beq(r1: Register, r2: Register, offset: i13) Instruction {
346 return bType(0b1100011, 0b000, r1, r2, offset);
347 }
348
349 pub fn bne(r1: Register, r2: Register, offset: i13) Instruction {
350 return bType(0b1100011, 0b001, r1, r2, offset);
351 }
352
353 pub fn blt(r1: Register, r2: Register, offset: i13) Instruction {
354 return bType(0b1100011, 0b100, r1, r2, offset);
355 }
356
357 pub fn bge(r1: Register, r2: Register, offset: i13) Instruction {
358 return bType(0b1100011, 0b101, r1, r2, offset);
359 }
360
361 pub fn bltu(r1: Register, r2: Register, offset: i13) Instruction {
362 return bType(0b1100011, 0b110, r1, r2, offset);
363 }
364
365 pub fn bgeu(r1: Register, r2: Register, offset: i13) Instruction {
366 return bType(0b1100011, 0b111, r1, r2, offset);
367 }
368
369 // Jump
370
371 pub fn jal(link: Register, offset: i21) Instruction {
372 return jType(0b1101111, link, offset);
373 }
374
375 pub fn jalr(link: Register, offset: i12, base: Register) Instruction {
376 return iType(0b1100111, 0b000, link, base, offset);
140 pub fn asBits(imm: Immediate, comptime T: type) T {
141 const int_info = @typeInfo(T).Int;
142 if (int_info.signedness != .unsigned) @compileError("Immediate.asBits needs unsigned T");
143 return switch (imm) {
144 .signed => |x| @bitCast(@as(std.meta.Int(.signed, int_info.bits), @intCast(x))),
145 .unsigned => |x| @intCast(x),
146 };
377147 }
378
379 // System
380
381 pub const ecall = iType(0b1110011, 0b000, .zero, .zero, 0x000);
382 pub const ebreak = iType(0b1110011, 0b000, .zero, .zero, 0x001);
383 pub const unimp = iType(0, 0, .zero, .zero, 0);
384148};
385149
386150pub const Register = enum(u6) {
......@@ -404,50 +168,63 @@ pub const Register = enum(u6) {
404168 t3, t4, t5, t6, // caller saved
405169 // zig fmt: on
406170
407 /// Returns the unique 4-bit ID of this register which is used in
171 /// Returns the unique 5-bit ID of this register which is used in
408172 /// the machine code
409173 pub fn id(self: Register) u5 {
410174 return @as(u5, @truncate(@intFromEnum(self)));
411175 }
412176
413177 pub fn dwarfLocOp(reg: Register) u8 {
414 return @as(u8, reg.id()) + DW.OP.reg0;
178 return @as(u8, reg.id());
415179 }
416180};
417181
418// zig fmt: on
419
420test "serialize instructions" {
421 const Testcase = struct {
422 inst: Instruction,
423 expected: u32,
424 };
425
426 const testcases = [_]Testcase{
427 .{ // add t6, zero, zero
428 .inst = Instruction.add(.t6, .zero, .zero),
429 .expected = 0b0000000_00000_00000_000_11111_0110011,
430 },
431 .{ // sd s0, 0x7f(s0)
432 .inst = Instruction.sd(.s0, 0x7f, .s0),
433 .expected = 0b0000011_01000_01000_011_11111_0100011,
434 },
435 .{ // bne s0, s1, 0x42
436 .inst = Instruction.bne(.s0, .s1, 0x42),
437 .expected = 0b0_000010_01001_01000_001_0001_0_1100011,
438 },
439 .{ // j 0x1a
440 .inst = Instruction.jal(.zero, 0x1a),
441 .expected = 0b0_0000001101_0_00000000_00000_1101111,
442 },
443 .{ // ebreak
444 .inst = Instruction.ebreak,
445 .expected = 0b000000000001_00000_000_00000_1110011,
446 },
447 };
448
449 for (testcases) |case| {
450 const actual = case.inst.toU32();
451 try testing.expectEqual(case.expected, actual);
182pub const FrameIndex = enum(u32) {
183 /// This index refers to the return address.
184 ret_addr,
185 /// This index refers to the frame pointer.
186 base_ptr,
187 /// This index refers to the entire stack frame.
188 stack_frame,
189 /// This index referes to where in the stack frame the args are spilled to.
190 args_frame,
191 /// This index referes to a frame dedicated to setting up args for function called
192 /// in this function. Useful for aligning args separately.
193 call_frame,
194 /// This index referes to the frame where callee saved registers are spilled and restore
195 /// from.
196 spill_frame,
197 /// Other indices are used for local variable stack slots
198 _,
199
200 pub const named_count = @typeInfo(FrameIndex).Enum.fields.len;
201
202 pub fn isNamed(fi: FrameIndex) bool {
203 return @intFromEnum(fi) < named_count;
204 }
205
206 pub fn format(
207 fi: FrameIndex,
208 comptime fmt: []const u8,
209 options: std.fmt.FormatOptions,
210 writer: anytype,
211 ) @TypeOf(writer).Error!void {
212 try writer.writeAll("FrameIndex");
213 if (fi.isNamed()) {
214 try writer.writeByte('.');
215 try writer.writeAll(@tagName(fi));
216 } else {
217 try writer.writeByte('(');
218 try std.fmt.formatType(@intFromEnum(fi), fmt, options, writer, 0);
219 try writer.writeByte(')');
220 }
452221 }
453}
222};
223
224/// A linker symbol not yet allocated in VM.
225pub const Symbol = struct {
226 /// Index of the containing atom.
227 atom_index: u32,
228 /// Index into the linker's symbol table.
229 sym_index: u32,
230};
src/arch/riscv64/encoder.zig created+49
......@@ -0,0 +1,49 @@
1pub const Instruction = struct {
2 encoding: Encoding,
3 ops: [3]Operand = .{.none} ** 3,
4
5 pub const Operand = union(enum) {
6 none,
7 reg: Register,
8 mem: Memory,
9 imm: Immediate,
10 };
11
12 pub fn new(mnemonic: Encoding.Mnemonic, ops: []const Operand) !Instruction {
13 const encoding = (try Encoding.findByMnemonic(mnemonic, ops)) orelse {
14 std.log.err("no encoding found for: {s} {s} {s} {s} {s}", .{
15 @tagName(mnemonic),
16 @tagName(if (ops.len > 0) ops[0] else .none),
17 @tagName(if (ops.len > 1) ops[1] else .none),
18 @tagName(if (ops.len > 2) ops[2] else .none),
19 @tagName(if (ops.len > 3) ops[3] else .none),
20 });
21 return error.InvalidInstruction;
22 };
23
24 var result_ops: [3]Operand = .{.none} ** 3;
25 @memcpy(result_ops[0..ops.len], ops);
26
27 return .{
28 .encoding = encoding,
29 .ops = result_ops,
30 };
31 }
32
33 pub fn encode(inst: Instruction, writer: anytype) !void {
34 try writer.writeInt(u32, inst.encoding.data.toU32(), .little);
35 }
36};
37
38const std = @import("std");
39
40const Lower = @import("Lower.zig");
41const Mir = @import("Mir.zig");
42const bits = @import("bits.zig");
43const Encoding = @import("Encoding.zig");
44
45const Register = bits.Register;
46const Memory = bits.Memory;
47const Immediate = bits.Immediate;
48
49const log = std.log.scoped(.encode);
src/codegen/llvm.zig+2
......@@ -11132,6 +11132,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
1113211132 }
1113311133 return o.builder.structType(.normal, types[0..types_len]);
1113411134 },
11135 .none => unreachable,
1113511136 }
1113611137 },
1113711138 // TODO investigate C ABI for other architectures
......@@ -11389,6 +11390,7 @@ const ParamTypeIterator = struct {
1138911390 it.llvm_index += it.types_len - 1;
1139011391 return .multiple_llvm_types;
1139111392 },
11393 .none => unreachable,
1139211394 }
1139311395 },
1139411396 // TODO investigate C ABI for other architectures
src/link/Elf.zig+2
......@@ -6409,6 +6409,8 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
64096409// TODO: add comptime check we don't clobber any reloc for any ISA
64106410pub const R_ZIG_GOT32: u32 = 0xff00;
64116411pub const R_ZIG_GOTPCREL: u32 = 0xff01;
6412pub const R_ZIG_GOT_HI20: u32 = 0xff02;
6413pub const R_ZIG_GOT_LO12: u32 = 0xff03;
64126414
64136415fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
64146416 return switch (cpu_arch) {
src/link/Elf/Atom.zig+25-3
......@@ -2025,7 +2025,15 @@ const riscv = struct {
20252025 .SUB32,
20262026 => {},
20272027
2028 else => try atom.reportUnhandledRelocError(rel, elf_file),
2028 else => |x| switch (@intFromEnum(x)) {
2029 Elf.R_ZIG_GOT_HI20,
2030 Elf.R_ZIG_GOT_LO12,
2031 => {
2032 assert(symbol.flags.has_zig_got);
2033 },
2034
2035 else => try atom.reportUnhandledRelocError(rel, elf_file),
2036 },
20292037 }
20302038 }
20312039
......@@ -2046,7 +2054,6 @@ const riscv = struct {
20462054 const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args;
20472055 _ = TP;
20482056 _ = DTP;
2049 _ = ZIG_GOT;
20502057
20512058 switch (r_type) {
20522059 .NONE => unreachable,
......@@ -2136,7 +2143,22 @@ const riscv = struct {
21362143 }
21372144 },
21382145
2139 else => try atom.reportUnhandledRelocError(rel, elf_file),
2146 else => |x| switch (@intFromEnum(x)) {
2147 // Zig custom relocations
2148 Elf.R_ZIG_GOT_HI20 => {
2149 assert(target.flags.has_zig_got);
2150 const disp: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);
2151 riscv_util.writeInstU(code[r_offset..][0..4], disp);
2152 },
2153
2154 Elf.R_ZIG_GOT_LO12 => {
2155 assert(target.flags.has_zig_got);
2156 const value: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);
2157 riscv_util.writeInstI(code[r_offset..][0..4], value);
2158 },
2159
2160 else => try atom.reportUnhandledRelocError(rel, elf_file),
2161 },
21402162 }
21412163 }
21422164
src/link/riscv.zig+47-18
......@@ -25,38 +25,66 @@ pub fn writeAddend(
2525}
2626
2727pub fn writeInstU(code: *[4]u8, value: u32) void {
28 var inst = Instruction{
28 var data = Encoding.Data{
2929 .U = mem.bytesToValue(std.meta.TagPayload(
30 Instruction,
31 Instruction.U,
30 Encoding.Data,
31 Encoding.Data.U,
3232 ), code),
3333 };
3434 const compensated: u32 = @bitCast(@as(i32, @bitCast(value)) + 0x800);
35 inst.U.imm12_31 = bitSlice(compensated, 31, 12);
36 mem.writeInt(u32, code, inst.toU32(), .little);
35 data.U.imm12_31 = bitSlice(compensated, 31, 12);
36 mem.writeInt(u32, code, data.toU32(), .little);
3737}
3838
3939pub fn writeInstI(code: *[4]u8, value: u32) void {
40 var inst = Instruction{
40 var data = Encoding.Data{
4141 .I = mem.bytesToValue(std.meta.TagPayload(
42 Instruction,
43 Instruction.I,
42 Encoding.Data,
43 Encoding.Data.I,
4444 ), code),
4545 };
46 inst.I.imm0_11 = bitSlice(value, 11, 0);
47 mem.writeInt(u32, code, inst.toU32(), .little);
46 data.I.imm0_11 = bitSlice(value, 11, 0);
47 mem.writeInt(u32, code, data.toU32(), .little);
4848}
4949
5050pub fn writeInstS(code: *[4]u8, value: u32) void {
51 var inst = Instruction{
51 var data = Encoding.Data{
5252 .S = mem.bytesToValue(std.meta.TagPayload(
53 Instruction,
54 Instruction.S,
53 Encoding.Data,
54 Encoding.Data.S,
5555 ), code),
5656 };
57 inst.S.imm0_4 = bitSlice(value, 4, 0);
58 inst.S.imm5_11 = bitSlice(value, 11, 5);
59 mem.writeInt(u32, code, inst.toU32(), .little);
57 data.S.imm0_4 = bitSlice(value, 4, 0);
58 data.S.imm5_11 = bitSlice(value, 11, 5);
59 mem.writeInt(u32, code, data.toU32(), .little);
60}
61
62pub fn writeInstJ(code: *[4]u8, value: u32) void {
63 var data = Encoding.Data{
64 .J = mem.bytesToValue(std.meta.TagPayload(
65 Encoding.Data,
66 Encoding.Data.J,
67 ), code),
68 };
69 data.J.imm1_10 = bitSlice(value, 10, 1);
70 data.J.imm11 = bitSlice(value, 11, 11);
71 data.J.imm12_19 = bitSlice(value, 19, 12);
72 data.J.imm20 = bitSlice(value, 20, 20);
73 mem.writeInt(u32, code, data.toU32(), .little);
74}
75
76pub fn writeInstB(code: *[4]u8, value: u32) void {
77 var data = Encoding.Data{
78 .B = mem.bytesToValue(std.meta.TagPayload(
79 Encoding.Data,
80 Encoding.Data.B,
81 ), code),
82 };
83 data.B.imm1_4 = bitSlice(value, 4, 1);
84 data.B.imm5_10 = bitSlice(value, 10, 5);
85 data.B.imm11 = bitSlice(value, 11, 11);
86 data.B.imm12 = bitSlice(value, 12, 12);
87 mem.writeInt(u32, code, data.toU32(), .little);
6088}
6189
6290fn bitSlice(
......@@ -67,8 +95,9 @@ fn bitSlice(
6795 return @truncate((value >> low) & (1 << (high - low + 1)) - 1);
6896}
6997
70const bits = @import("../arch/riscv64/bits.zig");
98const encoder = @import("../arch/riscv64/encoder.zig");
99const Encoding = @import("../arch/riscv64/Encoding.zig");
71100const mem = std.mem;
72101const std = @import("std");
73102
74pub const Instruction = bits.Instruction;
103pub const Instruction = encoder.Instruction;
src/register_manager.zig+2-1
......@@ -102,7 +102,7 @@ pub fn RegisterManager(
102102 }
103103
104104 const OptionalIndex = std.math.IntFittingRange(0, set.len);
105 comptime var map = [1]OptionalIndex{set.len} ** (max_id + 1 - min_id);
105 comptime var map = [1]OptionalIndex{set.len} ** (max_id - min_id + 1);
106106 inline for (set, 0..) |elem, elem_index| map[comptime elem.id() - min_id] = elem_index;
107107
108108 const id_index = reg.id() -% min_id;
......@@ -360,6 +360,7 @@ pub fn RegisterManager(
360360 } else self.getRegIndexAssumeFree(tracked_index, inst);
361361 }
362362 pub fn getReg(self: *Self, reg: Register, inst: ?Air.Inst.Index) AllocateRegistersError!void {
363 log.debug("getting reg: {}", .{reg});
363364 return self.getRegIndex(indexOfRegIntoTracked(reg) orelse return, inst);
364365 }
365366 pub fn getKnownReg(
src/target.zig+2-2
......@@ -507,7 +507,7 @@ pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBacken
507507 if (use_llvm) return .stage2_llvm;
508508 if (target.ofmt == .c) return .stage2_c;
509509 return switch (target.cpu.arch) {
510 .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,
510 .wasm32, .wasm64 => .stage2_wasm,
511511 .arm, .armeb, .thumb, .thumbeb => .stage2_arm,
512512 .x86_64 => .stage2_x86_64,
513513 .x86 => .stage2_x86,
......@@ -526,7 +526,7 @@ pub fn backendSupportsFeature(
526526 feature: Feature,
527527) bool {
528528 return switch (feature) {
529 .panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64,
529 .panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64 or cpu_arch == .riscv64,
530530 .panic_unwrap_error => ofmt == .c or use_llvm,
531531 .safety_check_formatted => ofmt == .c or use_llvm,
532532 .error_return_trace => use_llvm,
test/behavior/abs.zig+5-6
......@@ -5,8 +5,8 @@ const expect = std.testing.expect;
55test "@abs integers" {
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1010
1111 try comptime testAbsIntegers();
1212 try testAbsIntegers();
......@@ -51,7 +51,6 @@ fn testAbsIntegers() !void {
5151test "@abs unsigned integers" {
5252 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
54 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
5554 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5655
5756 try comptime testAbsUnsignedIntegers();
......@@ -92,9 +91,9 @@ fn testAbsUnsignedIntegers() !void {
9291test "@abs floats" {
9392 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9493 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
95 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
9694 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9795 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
96 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9897
9998 try comptime testAbsFloats(f16);
10099 try testAbsFloats(f16);
......@@ -151,8 +150,8 @@ test "@abs int vectors" {
151150 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
152151 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
153152 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
155153 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
156155
157156 try comptime testAbsIntVectors(1);
158157 try testAbsIntVectors(1);
......@@ -218,8 +217,8 @@ test "@abs unsigned int vectors" {
218217 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
219218 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
220219 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
221 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
222220 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
221 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
223222
224223 try comptime testAbsUnsignedIntVectors(1);
225224 try testAbsUnsignedIntVectors(1);
......@@ -277,9 +276,9 @@ test "@abs float vectors" {
277276 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
278277 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
279278 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
280 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
281279 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
282280 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
281 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
283282
284283 // https://github.com/ziglang/zig/issues/12827
285284 if (builtin.zig_backend == .stage2_llvm and
test/behavior/align.zig+16
......@@ -16,6 +16,7 @@ test "global variable alignment" {
1616}
1717
1818test "large alignment of local constant" {
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1920 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2021 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2122 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
......@@ -25,6 +26,7 @@ test "large alignment of local constant" {
2526}
2627
2728test "slicing array of length 1 can not assume runtime index is always zero" {
29 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
2830 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2931 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3032 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
......@@ -52,6 +54,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
5254}
5355
5456test "@alignCast pointers" {
57 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
5558 var x: u32 align(4) = 1;
5659 expectsOnly1(&x);
5760 try expect(x == 2);
......@@ -235,6 +238,7 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
235238}
236239
237240test "specifying alignment allows pointer cast" {
241 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
238242 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
239243 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
240244
......@@ -247,6 +251,7 @@ fn testBytesAlign(b: u8) !void {
247251}
248252
249253test "@alignCast slices" {
254 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
250255 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
251256 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
252257 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -265,6 +270,7 @@ fn sliceExpects4(slice: []align(4) u32) void {
265270}
266271
267272test "return error union with 128-bit integer" {
273 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
268274 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
269275 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
270276 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -277,6 +283,7 @@ fn give() anyerror!u128 {
277283}
278284
279285test "page aligned array on stack" {
286 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
280287 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
281288 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
282289 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -305,6 +312,7 @@ test "function alignment" {
305312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
306313 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
307314 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
315 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
308316
309317 // function alignment is a compile error on wasm32/wasm64
310318 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
......@@ -418,6 +426,7 @@ test "function callconv expression depends on generic parameter" {
418426}
419427
420428test "runtime-known array index has best alignment possible" {
429 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
421430 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
422431
423432 // take full advantage of over-alignment
......@@ -478,6 +487,7 @@ const DefaultAligned = struct {
478487};
479488
480489test "read 128-bit field from default aligned struct in stack memory" {
490 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
481491 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
482492 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
483493 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -497,6 +507,7 @@ var default_aligned_global = DefaultAligned{
497507};
498508
499509test "read 128-bit field from default aligned struct in global memory" {
510 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
500511 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
501512 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
502513 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -506,6 +517,7 @@ test "read 128-bit field from default aligned struct in global memory" {
506517}
507518
508519test "struct field explicit alignment" {
520 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
509521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
510522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
511523 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -550,6 +562,7 @@ test "align(@alignOf(T)) T does not force resolution of T" {
550562}
551563
552564test "align(N) on functions" {
565 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
553566 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
554567 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
555568 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -595,6 +608,7 @@ test "comptime alloc alignment" {
595608}
596609
597610test "@alignCast null" {
611 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
598612 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
599613 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
600614
......@@ -610,6 +624,7 @@ test "alignment of slice element" {
610624}
611625
612626test "sub-aligned pointer field access" {
627 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
613628 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
614629 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
615630 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
......@@ -658,6 +673,7 @@ test "alignment of zero-bit types is respected" {
658673}
659674
660675test "zero-bit fields in extern struct pad fields appropriately" {
676 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
661677 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
662678 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
663679 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
test/behavior/alignof.zig+2
......@@ -29,6 +29,8 @@ test "comparison of @alignOf(T) against zero" {
2929}
3030
3131test "correct alignment for elements and slices of aligned array" {
32 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
33
3234 var buf: [1024]u8 align(64) = undefined;
3335 var start: usize = 1;
3436 var end: usize = undefined;
test/behavior/array.zig+45
......@@ -22,6 +22,7 @@ test "arrays" {
2222 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2323 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2424 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2526
2627 var array: [5]u32 = undefined;
2728
......@@ -49,6 +50,7 @@ fn getArrayLen(a: []const u32) usize {
4950test "array concat with undefined" {
5051 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5152 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
53 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5254
5355 const S = struct {
5456 fn doTheTest() !void {
......@@ -87,6 +89,7 @@ test "array concat with tuple" {
8789
8890test "array init with concat" {
8991 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9093
9194 const a = 'a';
9295 var i: [4]u8 = [2]u8{ a, 'b' } ++ [2]u8{ 'c', 'd' };
......@@ -96,6 +99,7 @@ test "array init with concat" {
9699test "array init with mult" {
97100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
98101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
102 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
99103
100104 const a = 'a';
101105 var i: [8]u8 = [2]u8{ a, 'b' } ** 4;
......@@ -159,6 +163,7 @@ test "array len field" {
159163test "array with sentinels" {
160164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
161165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
166 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
162167
163168 const S = struct {
164169 fn doTheTest(is_ct: bool) !void {
......@@ -226,6 +231,7 @@ test "nested arrays of integers" {
226231test "implicit comptime in array type size" {
227232 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
228233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
234 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
229235
230236 var arr: [plusOne(10)]bool = undefined;
231237 _ = &arr;
......@@ -239,6 +245,7 @@ fn plusOne(x: u32) u32 {
239245test "single-item pointer to array indexing and slicing" {
240246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
241247 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
248 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
242249
243250 try testSingleItemPtrArrayIndexSlice();
244251 try comptime testSingleItemPtrArrayIndexSlice();
......@@ -264,6 +271,7 @@ fn doSomeMangling(array: *[4]u8) void {
264271
265272test "implicit cast zero sized array ptr to slice" {
266273 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
274 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
267275
268276 {
269277 var b = "".*;
......@@ -302,6 +310,7 @@ const Str = struct { a: []Sub };
302310test "set global var array via slice embedded in struct" {
303311 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
304312 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
313 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
305314
306315 var s = Str{ .a = s_array[0..] };
307316
......@@ -338,6 +347,7 @@ test "read/write through global variable array of struct fields initialized via
338347test "implicit cast single-item pointer" {
339348 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
340349 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
350 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
341351
342352 try testImplicitCastSingleItemPtr();
343353 try comptime testImplicitCastSingleItemPtr();
......@@ -368,6 +378,7 @@ test "comptime evaluating function that takes array by value" {
368378test "runtime initialize array elem and then implicit cast to slice" {
369379 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
370380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
381 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
371382
372383 var two: i32 = 2;
373384 _ = &two;
......@@ -378,6 +389,7 @@ test "runtime initialize array elem and then implicit cast to slice" {
378389test "array literal as argument to function" {
379390 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
380391 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
392 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
381393
382394 const S = struct {
383395 fn entry(two: i32) !void {
......@@ -406,6 +418,7 @@ test "double nested array to const slice cast in array literal" {
406418 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
407419 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
408420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
421 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
409422
410423 const S = struct {
411424 fn entry(two: i32) !void {
......@@ -492,6 +505,7 @@ test "anonymous literal in array" {
492505test "access the null element of a null terminated array" {
493506 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
494507 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
495509
496510 const S = struct {
497511 fn doTheTest() !void {
......@@ -511,6 +525,7 @@ test "type deduction for array subscript expression" {
511525 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
512526 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
513527 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
528 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
514529
515530 const S = struct {
516531 fn doTheTest() !void {
......@@ -530,6 +545,7 @@ test "sentinel element count towards the ABI size calculation" {
530545 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
531546 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
532547 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
548 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
533549
534550 const S = struct {
535551 fn doTheTest() !void {
......@@ -577,6 +593,7 @@ test "type coercion of anon struct literal to array" {
577593 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
578594 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
579595 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
596 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
580597
581598 const S = struct {
582599 const U = union {
......@@ -611,6 +628,7 @@ test "type coercion of pointer to anon struct literal to pointer to array" {
611628 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
612629 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
613630 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
631 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
614632
615633 const S = struct {
616634 const U = union {
......@@ -663,6 +681,7 @@ test "array init of container level array variable" {
663681 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
664682 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
665683 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
684 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
666685
667686 const S = struct {
668687 var pair: [2]usize = .{ 1, 2 };
......@@ -683,6 +702,8 @@ test "array init of container level array variable" {
683702}
684703
685704test "runtime initialized sentinel-terminated array literal" {
705 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
706
686707 var c: u16 = 300;
687708 _ = &c;
688709 const f = &[_:0x9999]u16{c};
......@@ -695,6 +716,7 @@ test "array of array agregate init" {
695716 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
696717 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
697718 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
719 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
698720
699721 var a = [1]u32{11} ** 10;
700722 var b = [1][10]u32{a} ** 2;
......@@ -745,6 +767,7 @@ test "slicing array of zero-sized values" {
745767 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
746768 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
747769 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
770 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
748771
749772 var arr: [32]u0 = undefined;
750773 for (arr[0..]) |*zero|
......@@ -754,6 +777,8 @@ test "slicing array of zero-sized values" {
754777}
755778
756779test "array init with no result pointer sets field result types" {
780 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
781
757782 const S = struct {
758783 // A function parameter has a result type, but no result pointer.
759784 fn f(arr: [1]u32) u32 {
......@@ -768,6 +793,8 @@ test "array init with no result pointer sets field result types" {
768793}
769794
770795test "runtime side-effects in comptime-known array init" {
796 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
797
771798 var side_effects: u4 = 0;
772799 const init = [4]u4{
773800 blk: {
......@@ -792,6 +819,8 @@ test "runtime side-effects in comptime-known array init" {
792819}
793820
794821test "slice initialized through reference to anonymous array init provides result types" {
822 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
823
795824 var my_u32: u32 = 123;
796825 var my_u64: u64 = 456;
797826 _ = .{ &my_u32, &my_u64 };
......@@ -805,6 +834,8 @@ test "slice initialized through reference to anonymous array init provides resul
805834}
806835
807836test "sentinel-terminated slice initialized through reference to anonymous array init provides result types" {
837 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
838
808839 var my_u32: u32 = 123;
809840 var my_u64: u64 = 456;
810841 _ = .{ &my_u32, &my_u64 };
......@@ -818,6 +849,8 @@ test "sentinel-terminated slice initialized through reference to anonymous array
818849}
819850
820851test "many-item pointer initialized through reference to anonymous array init provides result types" {
852 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
853
821854 var my_u32: u32 = 123;
822855 var my_u64: u64 = 456;
823856 _ = .{ &my_u32, &my_u64 };
......@@ -834,6 +867,8 @@ test "many-item pointer initialized through reference to anonymous array init pr
834867}
835868
836869test "many-item sentinel-terminated pointer initialized through reference to anonymous array init provides result types" {
870 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
871
837872 var my_u32: u32 = 123;
838873 var my_u64: u64 = 456;
839874 _ = .{ &my_u32, &my_u64 };
......@@ -851,6 +886,8 @@ test "many-item sentinel-terminated pointer initialized through reference to ano
851886}
852887
853888test "pointer to array initialized through reference to anonymous array init provides result types" {
889 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
890
854891 var my_u32: u32 = 123;
855892 var my_u64: u64 = 456;
856893 _ = .{ &my_u32, &my_u64 };
......@@ -864,6 +901,8 @@ test "pointer to array initialized through reference to anonymous array init pro
864901}
865902
866903test "pointer to sentinel-terminated array initialized through reference to anonymous array init provides result types" {
904 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
905
867906 var my_u32: u32 = 123;
868907 var my_u64: u64 = 456;
869908 _ = .{ &my_u32, &my_u64 };
......@@ -890,6 +929,7 @@ test "copied array element doesn't alias source" {
890929 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
891930 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
892931 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
932 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
893933
894934 var x: [10][10]u32 = undefined;
895935
......@@ -902,6 +942,7 @@ test "copied array element doesn't alias source" {
902942
903943test "array initialized with string literal" {
904944 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
945 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
905946
906947 const S = struct {
907948 a: u32,
......@@ -922,6 +963,7 @@ test "array initialized with string literal" {
922963
923964test "array initialized with array with sentinel" {
924965 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
966 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
925967
926968 const S = struct {
927969 a: u32,
......@@ -969,6 +1011,7 @@ test "accessing multidimensional global array at comptime" {
9691011 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
9701012 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9711013 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1014 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9721015
9731016 const S = struct {
9741017 const array = [_][]const []const u8{
......@@ -985,6 +1028,7 @@ test "union that needs padding bytes inside an array" {
9851028 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9861029 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9871030 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1031 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9881032
9891033 const B = union(enum) {
9901034 D: u8,
......@@ -1006,6 +1050,7 @@ test "union that needs padding bytes inside an array" {
10061050
10071051test "runtime index of array of zero-bit values" {
10081052 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1053 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10091054
10101055 var runtime: struct { array: [1]void, index: usize } = undefined;
10111056 runtime = .{ .array = .{{}}, .index = 0 };
test/behavior/asm.zig+4
......@@ -46,6 +46,7 @@ test "output constraint modifiers" {
4646 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4747 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4848 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
49 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4950
5051 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
5152
......@@ -69,6 +70,7 @@ test "alternative constraints" {
6970 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7071 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7172 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
73 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7274
7375 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
7476
......@@ -87,6 +89,7 @@ test "sized integer/float in asm input" {
8789 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8890 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8991 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
92 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9093
9194 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
9295
......@@ -137,6 +140,7 @@ test "struct/array/union types as input values" {
137140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
139142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
140144
141145 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // MSVC doesn't support inline assembly
142146
test/behavior/atomics.zig+13
......@@ -15,6 +15,7 @@ test "cmpxchg" {
1515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1616 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1717 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1819
1920 try testCmpxchg();
2021 try comptime testCmpxchg();
......@@ -41,6 +42,7 @@ test "fence" {
4142 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4344 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
45 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4446
4547 var x: i32 = 1234;
4648 @fence(.seq_cst);
......@@ -52,6 +54,7 @@ test "atomicrmw and atomicload" {
5254 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5355 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5456 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
57 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5558
5659 var data: u8 = 200;
5760 try testAtomicRmw(&data);
......@@ -80,6 +83,7 @@ test "cmpxchg with ptr" {
8083 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8184 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8285 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
86 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8387
8488 var data1: i32 = 1234;
8589 var data2: i32 = 5678;
......@@ -105,6 +109,7 @@ test "cmpxchg with ignored result" {
105109 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
106110 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
107111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
108113
109114 var x: i32 = 1234;
110115
......@@ -149,6 +154,7 @@ test "cmpxchg on a global variable" {
149154 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
150155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
151156 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
157 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
152158
153159 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
154160 // https://github.com/ziglang/zig/issues/10627
......@@ -164,6 +170,7 @@ test "atomic load and rmw with enum" {
164170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
165171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
166172 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
173 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
167174
168175 const Value = enum(u8) { a, b, c };
169176 var x = Value.a;
......@@ -181,6 +188,7 @@ test "atomic store" {
181188 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
182189 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
183190 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
191 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
184192
185193 var x: u32 = 0;
186194 @atomicStore(u32, &x, 1, .seq_cst);
......@@ -194,6 +202,7 @@ test "atomic store comptime" {
194202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
195203 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
196204 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
205 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
197206
198207 try comptime testAtomicStore();
199208 try testAtomicStore();
......@@ -212,6 +221,7 @@ test "atomicrmw with floats" {
212221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
213222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
214223 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
215225
216226 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
217227 // https://github.com/ziglang/zig/issues/10627
......@@ -241,6 +251,7 @@ test "atomicrmw with ints" {
241251 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
242252 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
243253 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
254 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
244255
245256 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
246257 // https://github.com/ziglang/zig/issues/16846
......@@ -390,6 +401,7 @@ test "atomics with different types" {
390401 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
391402 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
392403 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
404 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
393405
394406 try testAtomicsWithType(bool, true, false);
395407
......@@ -419,6 +431,7 @@ test "return @atomicStore, using it as a void value" {
419431 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
420432 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
421433 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
434 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
422435
423436 const S = struct {
424437 const A = struct {
test/behavior/basic.zig+37
......@@ -16,6 +16,8 @@ test "empty function with comments" {
1616}
1717
1818test "truncate" {
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20
1921 try expect(testTruncate(0x10fd) == 0xfd);
2022 comptime assert(testTruncate(0x10fd) == 0xfd);
2123}
......@@ -25,6 +27,7 @@ fn testTruncate(x: u32) u8 {
2527
2628test "truncate to non-power-of-two integers" {
2729 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
30 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2831
2932 try testTrunc(u32, u1, 0b10101, 0b1);
3033 try testTrunc(u32, u1, 0b10110, 0b0);
......@@ -42,6 +45,7 @@ test "truncate to non-power-of-two integers from 128-bit" {
4245 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4346 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4447 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
48 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4549
4650 try testTrunc(u128, u1, 0xffffffff_ffffffff_ffffffff_01010101, 0x01);
4751 try testTrunc(u128, u1, 0xffffffff_ffffffff_ffffffff_01010110, 0x00);
......@@ -220,6 +224,7 @@ const OpaqueB = opaque {};
220224test "opaque types" {
221225 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
222226 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
227 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
223228
224229 try expect(*OpaqueA != *OpaqueB);
225230
......@@ -371,6 +376,7 @@ test "take address of parameter" {
371376 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
372377 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
373378 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
379 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
374380
375381 try testTakeAddressOfParameter(12.34);
376382}
......@@ -395,6 +401,7 @@ test "array 2D const double ptr" {
395401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
396402 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
397403 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
404 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
398405
399406 const rect_2d_vertexes = [_][1]f32{
400407 [_]f32{1.0},
......@@ -407,6 +414,7 @@ test "array 2D const double ptr with offset" {
407414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
408415 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
409416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
417 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
410418
411419 const rect_2d_vertexes = [_][2]f32{
412420 [_]f32{ 3.0, 4.239 },
......@@ -419,6 +427,7 @@ test "array 3D const double ptr with offset" {
419427 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
420428 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
421429 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
430 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
422431
423432 const rect_3d_vertexes = [_][2][2]f32{
424433 [_][2]f32{
......@@ -474,6 +483,7 @@ fn testStructInFn() !void {
474483
475484test "fn call returning scalar optional in equality expression" {
476485 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
486 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
477487 try expect(getNull() == null);
478488}
479489
......@@ -484,6 +494,7 @@ fn getNull() ?*i32 {
484494test "global variable assignment with optional unwrapping with var initialized to undefined" {
485495 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
486496 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
497 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
487498
488499 const S = struct {
489500 var data: i32 = 1234;
......@@ -502,6 +513,7 @@ var global_foo: *i32 = undefined;
502513test "peer result location with typed parent, runtime condition, comptime prongs" {
503514 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
504515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
516 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
505517
506518 const S = struct {
507519 fn doTheTest(arg: i32) i32 {
......@@ -581,6 +593,7 @@ test "equality compare fn ptrs" {
581593
582594test "self reference through fn ptr field" {
583595 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
596 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
584597
585598 const S = struct {
586599 const A = struct {
......@@ -613,6 +626,7 @@ var global_ptr = &gdt[0];
613626
614627test "global constant is loaded with a runtime-known index" {
615628 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
629 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
616630
617631 const S = struct {
618632 fn doTheTest() !void {
......@@ -631,6 +645,7 @@ test "global constant is loaded with a runtime-known index" {
631645
632646test "multiline string literal is null terminated" {
633647 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
648 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
634649
635650 const s1 =
636651 \\one
......@@ -645,6 +660,7 @@ test "string escapes" {
645660 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
646661 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
647662 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
663 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
648664
649665 try expectEqualStrings("\"", "\x22");
650666 try expectEqualStrings("\'", "\x27");
......@@ -674,6 +690,7 @@ test "string concatenation" {
674690 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
675691 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
676692 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
693 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
677694
678695 const a = "OK" ++ " IT " ++ "WORKED";
679696 const b = "OK IT WORKED";
......@@ -697,6 +714,7 @@ test "result location is optional inside error union" {
697714 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
698715 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
699716 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
717 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
700718
701719 const x = maybe(true) catch unreachable;
702720 try expect(x.? == 42);
......@@ -712,6 +730,7 @@ fn maybe(x: bool) anyerror!?u32 {
712730test "auto created variables have correct alignment" {
713731 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
714732 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
733 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
715734
716735 const S = struct {
717736 fn foo(str: [*]const u8) u32 {
......@@ -733,6 +752,7 @@ test "extern variable with non-pointer opaque type" {
733752 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
734753 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
735754 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
755 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
736756
737757 @export(var_to_export, .{ .name = "opaque_extern_var" });
738758 try expect(@as(*align(1) u32, @ptrCast(&opaque_extern_var)).* == 42);
......@@ -776,6 +796,7 @@ test "discarding the result of various expressions" {
776796 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
777797 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
778798 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
799 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
779800
780801 const S = struct {
781802 fn foo() !u32 {
......@@ -817,6 +838,7 @@ test "labeled block implicitly ends in a break" {
817838test "catch in block has correct result location" {
818839 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
819840 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
841 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
820842
821843 const S = struct {
822844 fn open() error{A}!@This() {
......@@ -848,6 +870,7 @@ test "labeled block with runtime branch forwards its result location type to bre
848870
849871test "try in labeled block doesn't cast to wrong type" {
850872 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
873 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
851874
852875 const S = struct {
853876 a: u32,
......@@ -874,6 +897,7 @@ test "weird array and tuple initializations" {
874897 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
875898 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
876899 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
900 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
877901
878902 const E = enum { a, b };
879903 const S = struct { e: E };
......@@ -992,6 +1016,7 @@ comptime {
9921016
9931017test "switch inside @as gets correct type" {
9941018 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1019 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9951020
9961021 var a: u32 = 0;
9971022 _ = &a;
......@@ -1058,6 +1083,7 @@ test "returning an opaque type from a function" {
10581083test "orelse coercion as function argument" {
10591084 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10601085 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1086 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10611087
10621088 const Loc = struct { start: i32 = -1 };
10631089 const Container = struct {
......@@ -1075,6 +1101,8 @@ test "orelse coercion as function argument" {
10751101}
10761102
10771103test "runtime-known globals initialized with undefined" {
1104 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1105
10781106 const S = struct {
10791107 var array: [10]u32 = [_]u32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
10801108 var vp: [*]u32 = undefined;
......@@ -1095,6 +1123,7 @@ test "arrays and vectors with big integers" {
10951123 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10961124 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10971125 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1126 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10981127
10991128 // TODO: only aarch64-windows didn't pass in the PR that added this code.
11001129 // figure out why if you can run this target.
......@@ -1119,6 +1148,8 @@ test "pointer to struct literal with runtime field is constant" {
11191148}
11201149
11211150test "integer compare" {
1151 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1152
11221153 const S = struct {
11231154 fn doTheTestSigned(comptime T: type) !void {
11241155 var z: T = 0;
......@@ -1215,6 +1246,8 @@ test "pointer to tuple field can be dereferenced at comptime" {
12151246}
12161247
12171248test "proper value is returned from labeled block" {
1249 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1250
12181251 const S = struct {
12191252 fn hash(v: *u32, key: anytype) void {
12201253 const Key = @TypeOf(key);
......@@ -1281,6 +1314,7 @@ test "break out of block based on comptime known values" {
12811314 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
12821315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12831316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1317 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12841318
12851319 const S = struct {
12861320 const source = "A-";
......@@ -1317,6 +1351,7 @@ test "allocation and looping over 3-byte integer" {
13171351 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13181352 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13191353 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1354 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13201355
13211356 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .macos) {
13221357 return error.SkipZigTest; // TODO
......@@ -1350,6 +1385,8 @@ test "allocation and looping over 3-byte integer" {
13501385}
13511386
13521387test "loading array from struct is not optimized away" {
1388 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1389
13531390 const S = struct {
13541391 arr: [1]u32 = .{0},
13551392 fn doTheTest(self: *@This()) !void {
test/behavior/bit_shifting.zig+2
......@@ -65,6 +65,7 @@ test "sharded table" {
6565 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6666 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
6767 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
68 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6869
6970 // realistic 16-way sharding
7071 try testShardedTable(u32, 4, 8);
......@@ -116,6 +117,7 @@ test "Saturating Shift Left where lhs is of a computed type" {
116117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
117118 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
118119 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
120 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
119121
120122 const S = struct {
121123 fn getIntShiftType(comptime T: type) type {
test/behavior/bitcast.zig+17
......@@ -10,6 +10,7 @@ const native_endian = builtin.target.cpu.arch.endian();
1010
1111test "@bitCast iX -> uX (32, 64)" {
1212 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1314
1415 const bit_values = [_]usize{ 32, 64 };
1516
......@@ -24,6 +25,7 @@ test "@bitCast iX -> uX (8, 16, 128)" {
2425 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2526 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2627 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
28 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2729
2830 const bit_values = [_]usize{ 8, 16, 128 };
2931
......@@ -39,6 +41,7 @@ test "@bitCast iX -> uX exotic integers" {
3941 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
4042 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4143 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
44 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4245
4346 const bit_values = [_]usize{ 1, 48, 27, 512, 493, 293, 125, 204, 112 };
4447
......@@ -83,6 +86,7 @@ test "bitcast uX to bytes" {
8386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8588 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
89 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8690
8791 const bit_values = [_]usize{ 1, 48, 27, 512, 493, 293, 125, 204, 112 };
8892 inline for (bit_values) |bits| {
......@@ -161,6 +165,7 @@ test "@bitCast packed structs at runtime and comptime" {
161165 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
162166 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
163167 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
168 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
164169
165170 const Full = packed struct {
166171 number: u16,
......@@ -187,6 +192,7 @@ test "@bitCast packed structs at runtime and comptime" {
187192test "@bitCast extern structs at runtime and comptime" {
188193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
189194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
195 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
190196
191197 const Full = extern struct {
192198 number: u16,
......@@ -221,6 +227,7 @@ test "bitcast packed struct to integer and back" {
221227 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
222228 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
223229 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
230 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
224231
225232 const LevelUpMove = packed struct {
226233 move_id: u9,
......@@ -243,6 +250,7 @@ test "bitcast packed struct to integer and back" {
243250test "implicit cast to error union by returning" {
244251 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
245252 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
253 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
246254
247255 const S = struct {
248256 fn entry() !void {
......@@ -272,6 +280,8 @@ test "comptime bitcast used in expression has the correct type" {
272280}
273281
274282test "bitcast passed as tuple element" {
283 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
284
275285 const S = struct {
276286 fn foo(args: anytype) !void {
277287 comptime assert(@TypeOf(args[0]) == f32);
......@@ -282,6 +292,8 @@ test "bitcast passed as tuple element" {
282292}
283293
284294test "triple level result location with bitcast sandwich passed as tuple element" {
295 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
296
285297 const S = struct {
286298 fn foo(args: anytype) !void {
287299 comptime assert(@TypeOf(args[0]) == f64);
......@@ -299,6 +311,7 @@ test "@bitCast packed struct of floats" {
299311 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
300312 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
301313 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
314 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
302315
303316 const Foo = packed struct {
304317 a: f16 = 0,
......@@ -337,6 +350,7 @@ test "comptime @bitCast packed struct to int and back" {
337350 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
338351 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
339352 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
353 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
340354
341355 if (builtin.zig_backend == .stage2_llvm and native_endian == .big) {
342356 // https://github.com/ziglang/zig/issues/13782
......@@ -401,6 +415,7 @@ test "bitcast vector to integer and back" {
401415 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
402416 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
403417 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
418 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
404419
405420 const arr: [16]bool = [_]bool{ true, false } ++ [_]bool{true} ** 14;
406421 var x: @Vector(16, bool) = @splat(true);
......@@ -426,6 +441,7 @@ test "bitcast nan float does not modify signaling bit" {
426441 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
427442 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
428443 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
444 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
429445
430446 // TODO: https://github.com/ziglang/zig/issues/14366
431447 if (builtin.zig_backend == .stage2_llvm and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
......@@ -482,6 +498,7 @@ test "@bitCast of packed struct of bools all true" {
482498 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
483499 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
484500 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
501 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
485502
486503 const P = packed struct {
487504 b0: bool,
test/behavior/bitreverse.zig+4
......@@ -16,6 +16,7 @@ test "@bitReverse" {
1616 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1717 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1818 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1920
2021 try comptime testBitReverse();
2122 try testBitReverse();
......@@ -121,6 +122,7 @@ test "bitReverse vectors u8" {
121122 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
122123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
123124 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
125 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
124126
125127 try comptime vector8();
126128 try vector8();
......@@ -141,6 +143,7 @@ test "bitReverse vectors u16" {
141143 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
142144 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
143145 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
146 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
144147
145148 try comptime vector16();
146149 try vector16();
......@@ -161,6 +164,7 @@ test "bitReverse vectors u24" {
161164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
162165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
163166 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
167 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
164168
165169 try comptime vector24();
166170 try vector24();
test/behavior/bool.zig+2
......@@ -9,6 +9,8 @@ test "bool literals" {
99}
1010
1111test "cast bool to int" {
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13
1214 const t = true;
1315 const f = false;
1416 try expectEqual(@as(u32, 1), @intFromBool(t));
test/behavior/builtin_functions_returning_void_or_noreturn.zig+1-1
......@@ -10,8 +10,8 @@ test {
1010 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1413 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1515
1616 var val: u8 = undefined;
1717 try testing.expectEqual({}, @atomicStore(u8, &val, 0, .unordered));
test/behavior/byteswap.zig+4
......@@ -3,6 +3,8 @@ const builtin = @import("builtin");
33const expect = std.testing.expect;
44
55test "@byteSwap integers" {
6 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7
68 if (builtin.zig_backend == .stage2_wasm) {
79 // TODO: Remove when self-hosted wasm supports more types for byteswap
810 const ByteSwapIntTest = struct {
......@@ -118,6 +120,7 @@ test "@byteSwap vectors u16" {
118120 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
119121 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
120122 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
123 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
121124
122125 try comptime vector16();
123126 try vector16();
......@@ -138,6 +141,7 @@ test "@byteSwap vectors u24" {
138141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
139142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
140143 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
144 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
141145
142146 try comptime vector24();
143147 try vector24();
test/behavior/byval_arg_var.zig+1
......@@ -5,6 +5,7 @@ var result: []const u8 = "wrong";
55
66test "pass string literal byvalue to a generic var param" {
77 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
89
910 start();
1011 blowUpStack(10);
test/behavior/call.zig+13
......@@ -60,6 +60,7 @@ test "tuple parameters" {
6060 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
6262 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
63 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6364
6465 const add = struct {
6566 fn add(a: i32, b: i32) i32 {
......@@ -93,6 +94,7 @@ test "result location of function call argument through runtime condition and st
9394 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9495 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9596 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9698
9799 const E = enum { a, b };
98100 const S = struct {
......@@ -112,6 +114,7 @@ test "result location of function call argument through runtime condition and st
112114
113115test "function call with 40 arguments" {
114116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
117 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
115118
116119 const S = struct {
117120 fn doTheTest(thirty_nine: i32) !void {
......@@ -271,6 +274,7 @@ test "forced tail call" {
271274 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
272275 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
273276 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
277 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
274278
275279 if (builtin.zig_backend == .stage2_llvm) {
276280 // Only attempt this test on targets we know have tail call support in LLVM.
......@@ -306,6 +310,7 @@ test "inline call preserves tail call" {
306310 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
307311 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
308312 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
313 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
309314
310315 if (builtin.zig_backend == .stage2_llvm) {
311316 // Only attempt this test on targets we know have tail call support in LLVM.
......@@ -339,6 +344,7 @@ test "inline call preserves tail call" {
339344test "inline call doesn't re-evaluate non generic struct" {
340345 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
341346 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
347 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
342348
343349 const S = struct {
344350 fn foo(f: struct { a: u8, b: u8 }) !void {
......@@ -405,6 +411,7 @@ test "recursive inline call with comptime known argument" {
405411test "inline while with @call" {
406412 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
407413 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
414 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
408415
409416 const S = struct {
410417 fn inc(a: *u32) void {
......@@ -420,6 +427,8 @@ test "inline while with @call" {
420427}
421428
422429test "method call as parameter type" {
430 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
431
423432 const S = struct {
424433 fn foo(x: anytype, y: @TypeOf(x).Inner()) @TypeOf(y) {
425434 return y;
......@@ -437,6 +446,7 @@ test "non-anytype generic parameters provide result type" {
437446 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
438447 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
439448 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
449 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
440450
441451 const S = struct {
442452 fn f(comptime T: type, y: T) !void {
......@@ -467,6 +477,7 @@ test "argument to generic function has correct result type" {
467477 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
468478 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
469479 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
480 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
470481
471482 const S = struct {
472483 fn foo(_: anytype, e: enum { a, b }) bool {
......@@ -502,6 +513,8 @@ test "call inline fn through pointer" {
502513}
503514
504515test "call coerced function" {
516 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
517
505518 const T = struct {
506519 x: f64,
507520 const T = @This();
test/behavior/call_tail.zig+2
......@@ -31,6 +31,8 @@ noinline fn insertionSort(data: []u64) void {
3131}
3232
3333test "arguments pointed to on stack into tailcall" {
34 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
35
3436 switch (builtin.cpu.arch) {
3537 .wasm32,
3638 .mips,
test/behavior/cast.zig+102
......@@ -24,6 +24,7 @@ test "peer type resolution: ?T and T" {
2424 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2525 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2626 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2728
2829 try expect(peerTypeTAndOptionalT(true, false).? == 0);
2930 try expect(peerTypeTAndOptionalT(false, false).? == 3);
......@@ -56,6 +57,8 @@ test "@intCast to comptime_int" {
5657}
5758
5859test "implicit cast comptime numbers to any type when the value fits" {
60 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
61
5962 const a: u64 = 255;
6063 var b: u8 = a;
6164 _ = &b;
......@@ -103,6 +106,7 @@ test "@floatFromInt" {
103106 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
104107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
105108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
106110
107111 const S = struct {
108112 fn doTheTest() !void {
......@@ -126,6 +130,7 @@ test "@floatFromInt(f80)" {
126130 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
127131 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
128132 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
133 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
129134
130135 const S = struct {
131136 fn doTheTest(comptime Int: type) !void {
......@@ -160,6 +165,7 @@ test "@intFromFloat" {
160165 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
161166 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
162167 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
168 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
163169
164170 try testIntFromFloats();
165171 try comptime testIntFromFloats();
......@@ -182,6 +188,7 @@ fn expectIntFromFloat(comptime F: type, f: F, comptime I: type, i: I) !void {
182188test "implicitly cast indirect pointer to maybe-indirect pointer" {
183189 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
184190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
191 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185192
186193 const S = struct {
187194 const Self = @This();
......@@ -242,6 +249,7 @@ test "coerce undefined to optional" {
242249 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
243250 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
244251 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
245253
246254 try expect(MakeType(void).getNull() == null);
247255 try expect(MakeType(void).getNonNull() != null);
......@@ -262,6 +270,7 @@ fn MakeType(comptime T: type) type {
262270test "implicit cast from *[N]T to [*c]T" {
263271 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
264272 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
273 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
265274
266275 var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
267276 var y: [*c]u16 = &x;
......@@ -299,6 +308,7 @@ test "peer result null and comptime_int" {
299308 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
300309 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
301310 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
311 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
302312
303313 const S = struct {
304314 fn blah(n: i32) ?i32 {
......@@ -323,6 +333,7 @@ test "peer result null and comptime_int" {
323333test "*const ?[*]const T to [*c]const [*c]const T" {
324334 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
325335 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
336 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
326337
327338 var array = [_]u8{ 'o', 'k' };
328339 const opt_array_ptr: ?[*]const u8 = &array;
......@@ -336,6 +347,7 @@ test "array coercion to undefined at runtime" {
336347 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
337348 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
338349 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
350 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
339351
340352 @setRuntimeSafety(true);
341353
......@@ -366,6 +378,7 @@ test "return u8 coercing into ?u32 return type" {
366378 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
367379 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
368380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
381 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
369382
370383 const S = struct {
371384 fn doTheTest() !void {
......@@ -400,6 +413,7 @@ test "peer type unsigned int to signed" {
400413test "expected [*c]const u8, found [*:0]const u8" {
401414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
402415 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
416 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
403417
404418 var a: [*:0]const u8 = "hello";
405419 _ = &a;
......@@ -413,6 +427,7 @@ test "explicit cast from integer to error type" {
413427 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
414428 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
415429 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
430 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
416431
417432 try testCastIntToErr(error.ItBroke);
418433 try comptime testCastIntToErr(error.ItBroke);
......@@ -442,6 +457,7 @@ test "implicitly cast from T to anyerror!?T" {
442457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
443458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
444459 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
460 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
445461
446462 try castToOptionalTypeError(1);
447463 try comptime castToOptionalTypeError(1);
......@@ -467,6 +483,7 @@ fn castToOptionalTypeError(z: i32) !void {
467483test "implicitly cast from [0]T to anyerror![]T" {
468484 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
469485 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
486 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
470487
471488 try testCastZeroArrayToErrSliceMut();
472489 try comptime testCastZeroArrayToErrSliceMut();
......@@ -484,6 +501,7 @@ test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
484501 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
485502 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
486503 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
504 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
487505
488506 const S = struct {
489507 fn doTheTest() anyerror!void {
......@@ -540,6 +558,7 @@ fn testCastConstArrayRefToConstSlice() !void {
540558test "peer type resolution: error and [N]T" {
541559 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
542560 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
561 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
543562
544563 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
545564 comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
......@@ -564,6 +583,7 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
564583test "single-item pointer of array to slice to unknown length pointer" {
565584 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
566585 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
586 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
567587
568588 try testCastPtrOfArrayToSliceAndPtr();
569589 try comptime testCastPtrOfArrayToSliceAndPtr();
......@@ -593,6 +613,7 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {
593613test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
594614 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
595615 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
616 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
596617
597618 const window_name = [1][*]const u8{"window name"};
598619 const x: [*]const ?[*]const u8 = &window_name;
......@@ -605,6 +626,7 @@ test "@intCast on vector" {
605626 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
606627 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
607628 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
629 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
608630
609631 const S = struct {
610632 fn doTheTest() !void {
......@@ -639,6 +661,7 @@ test "@floatCast cast down" {
639661 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
640662 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
641663 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
664 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
642665
643666 {
644667 var double: f64 = 0.001534;
......@@ -656,6 +679,7 @@ test "@floatCast cast down" {
656679test "peer type resolution: unreachable, error set, unreachable" {
657680 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
658681 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
682 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
659683
660684 const Error = error{
661685 FileDescriptorAlreadyPresentInSet,
......@@ -750,6 +774,7 @@ test "peer type resolution: error union and error set" {
750774 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
751775 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
752776 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
777 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
753778
754779 const a: error{Three} = undefined;
755780 const b: error{ One, Two }!u32 = undefined;
......@@ -816,6 +841,7 @@ test "peer cast *[0]T to E![]const T" {
816841 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
817842 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
818843 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
844 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
819845
820846 var buffer: [5]u8 = "abcde".*;
821847 const buf: anyerror![]const u8 = buffer[0..];
......@@ -831,6 +857,7 @@ test "peer cast *[0]T to []const T" {
831857 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
832858 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
833859 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
860 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
834861
835862 var buffer: [5]u8 = "abcde".*;
836863 const buf: []const u8 = buffer[0..];
......@@ -854,6 +881,7 @@ test "peer resolution of string literals" {
854881 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
855882 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
856883 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
884 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
857885
858886 const S = struct {
859887 const E = enum { a, b, c, d };
......@@ -875,6 +903,7 @@ test "peer resolution of string literals" {
875903test "peer cast [:x]T to []T" {
876904 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
877905 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
906 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
878907
879908 const S = struct {
880909 fn doTheTest() !void {
......@@ -891,6 +920,7 @@ test "peer cast [:x]T to []T" {
891920test "peer cast [N:x]T to [N]T" {
892921 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
893922 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
923 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
894924
895925 const S = struct {
896926 fn doTheTest() !void {
......@@ -907,6 +937,7 @@ test "peer cast [N:x]T to [N]T" {
907937test "peer cast *[N:x]T to *[N]T" {
908938 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
909939 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
940 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910941
911942 const S = struct {
912943 fn doTheTest() !void {
......@@ -922,6 +953,7 @@ test "peer cast *[N:x]T to *[N]T" {
922953test "peer cast [*:x]T to [*]T" {
923954 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
924955 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
956 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
925957
926958 const S = struct {
927959 fn doTheTest() !void {
......@@ -942,6 +974,7 @@ test "peer cast [:x]T to [*:x]T" {
942974 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
943975 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
944976 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
977 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
945978
946979 const S = struct {
947980 fn doTheTest() !void {
......@@ -962,6 +995,7 @@ test "peer cast [:x]T to [*:x]T" {
962995test "peer type resolution implicit cast to return type" {
963996 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
964997 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
998 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
965999
9661000 const S = struct {
9671001 fn doTheTest() !void {
......@@ -982,6 +1016,7 @@ test "peer type resolution implicit cast to return type" {
9821016test "peer type resolution implicit cast to variable type" {
9831017 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9841018 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1019 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9851020
9861021 const S = struct {
9871022 fn doTheTest() !void {
......@@ -1007,6 +1042,7 @@ test "variable initialization uses result locations properly with regards to the
10071042test "cast between C pointer with different but compatible types" {
10081043 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10091044 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1045 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10101046
10111047 const S = struct {
10121048 fn foo(arg: [*]c_ushort) u16 {
......@@ -1024,6 +1060,7 @@ test "cast between C pointer with different but compatible types" {
10241060test "peer type resolve string lit with sentinel-terminated mutable slice" {
10251061 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10261062 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1063 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10271064
10281065 var array: [4:0]u8 = undefined;
10291066 array[4] = 0; // TODO remove this when #4372 is solved
......@@ -1090,6 +1127,7 @@ test "implicit cast from [*]T to ?*anyopaque" {
10901127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10911128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10921129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1130 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10931131
10941132 var a = [_]u8{ 3, 2, 1 };
10951133 var runtime_zero: usize = 0;
......@@ -1120,6 +1158,7 @@ fn foobar(func: PFN_void) !void {
11201158
11211159test "cast function with an opaque parameter" {
11221160 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1161 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11231162
11241163 if (builtin.zig_backend == .stage2_c) {
11251164 // https://github.com/ziglang/zig/issues/16845
......@@ -1152,6 +1191,7 @@ test "implicit ptr to *anyopaque" {
11521191 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11531192 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11541193 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11551195
11561196 var a: u32 = 1;
11571197 const ptr: *align(@alignOf(u32)) anyopaque = &a;
......@@ -1165,6 +1205,7 @@ test "implicit ptr to *anyopaque" {
11651205test "return null from fn () anyerror!?&T" {
11661206 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11671207 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1208 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11681209
11691210 const a = returnNullFromOptionalTypeErrorRef();
11701211 const b = returnNullLitFromOptionalTypeErrorRef();
......@@ -1181,6 +1222,7 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
11811222test "peer type resolution: [0]u8 and []const u8" {
11821223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11831224 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1225 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11841226
11851227 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
11861228 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
......@@ -1201,6 +1243,7 @@ test "implicitly cast from [N]T to ?[]const T" {
12011243 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12021244 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12031245 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1246 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12041247
12051248 try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
12061249 comptime assert(mem.eql(u8, castToOptionalSlice().?, "hi"));
......@@ -1215,6 +1258,7 @@ test "cast u128 to f128 and back" {
12151258 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12161259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12171260 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1261 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12181262
12191263 try comptime testCast128();
12201264 try testCast128();
......@@ -1236,6 +1280,7 @@ test "implicit cast from *[N]T to ?[*]T" {
12361280 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12371281 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12381282 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1283 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12391284
12401285 var x: ?[*]u16 = null;
12411286 var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
......@@ -1251,6 +1296,7 @@ test "implicit cast from *T to ?*anyopaque" {
12511296 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12521297 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12531298 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1299 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12541300
12551301 var a: u8 = 1;
12561302 incrementVoidPtrValue(&a);
......@@ -1264,6 +1310,7 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void {
12641310test "implicit cast *[0]T to E![]const u8" {
12651311 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12661312 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1313 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12671314
12681315 var x = @as(anyerror![]const u8, &[0]u8{});
12691316 _ = &x;
......@@ -1285,6 +1332,7 @@ test "*const [N]null u8 to ?[]const u8" {
12851332 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
12861333 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12871334 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1335 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12881336
12891337 const S = struct {
12901338 fn doTheTest() !void {
......@@ -1321,6 +1369,7 @@ test "assignment to optional pointer result loc" {
13211369 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
13221370 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13231371 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1372 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13241373
13251374 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
13261375 _ = &foo;
......@@ -1328,6 +1377,8 @@ test "assignment to optional pointer result loc" {
13281377}
13291378
13301379test "cast between *[N]void and []void" {
1380 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1381
13311382 var a: [4]void = undefined;
13321383 const b: []void = &a;
13331384 try expect(b.len == 4);
......@@ -1353,6 +1404,7 @@ test "cast f16 to wider types" {
13531404 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13541405 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
13551406 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1407 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13561408
13571409 const S = struct {
13581410 fn doTheTest() !void {
......@@ -1373,6 +1425,7 @@ test "cast f128 to narrower types" {
13731425 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13741426 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13751427 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1428 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13761429
13771430 const S = struct {
13781431 fn doTheTest() !void {
......@@ -1391,6 +1444,7 @@ test "peer type resolution: unreachable, null, slice" {
13911444 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
13921445 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13931446 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1447 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13941448
13951449 const S = struct {
13961450 fn doTheTest(num: usize, word: []const u8) !void {
......@@ -1431,6 +1485,7 @@ test "cast compatible optional types" {
14311485 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14321486 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14331487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1488 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14341489
14351490 var a: ?[:0]const u8 = null;
14361491 _ = &a;
......@@ -1441,6 +1496,7 @@ test "cast compatible optional types" {
14411496test "coerce undefined single-item pointer of array to error union of slice" {
14421497 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14431498 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1499 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14441500
14451501 const a = @as([*]u8, undefined)[0..0];
14461502 var b: error{a}![]const u8 = a;
......@@ -1464,6 +1520,7 @@ test "coerce between pointers of compatible differently-named floats" {
14641520 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14651521 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14661522 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1523 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14671524
14681525 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
14691526 // https://github.com/ziglang/zig/issues/12396
......@@ -1518,6 +1575,7 @@ test "cast typed undefined to int" {
15181575
15191576test "implicit cast from [:0]T to [*c]T" {
15201577 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1578 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15211579
15221580 var a: [:0]const u8 = "foo";
15231581 _ = &a;
......@@ -1541,6 +1599,7 @@ test "bitcast packed struct with u0" {
15411599
15421600test "optional pointer coerced to optional allowzero pointer" {
15431601 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1602 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15441603
15451604 var p: ?*u32 = undefined;
15461605 var q: ?*allowzero u32 = undefined;
......@@ -1557,6 +1616,8 @@ test "optional slice coerced to allowzero many pointer" {
15571616}
15581617
15591618test "optional slice passed as parameter coerced to allowzero many pointer" {
1619 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1620
15601621 const ns = struct {
15611622 const Color = struct {
15621623 r: u8,
......@@ -1576,6 +1637,8 @@ test "optional slice passed as parameter coerced to allowzero many pointer" {
15761637}
15771638
15781639test "single item pointer to pointer to array to slice" {
1640 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1641
15791642 var x: i32 = 1234;
15801643 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);
15811644 const z1 = @as([]const i32, @as(*[1]i32, &x));
......@@ -1583,6 +1646,8 @@ test "single item pointer to pointer to array to slice" {
15831646}
15841647
15851648test "peer type resolution forms error union" {
1649 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1650
15861651 var foo: i32 = 123;
15871652 _ = &foo;
15881653 const result = if (foo < 0) switch (-foo) {
......@@ -1616,6 +1681,8 @@ test "@volatileCast without a result location" {
16161681}
16171682
16181683test "coercion from single-item pointer to @as to slice" {
1684 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1685
16191686 var x: u32 = 1;
16201687
16211688 // Why the following line gets a compile error?
......@@ -1628,6 +1695,7 @@ test "peer type resolution: const sentinel slice and mutable non-sentinel slice"
16281695 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16291696 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16301697 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1698 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16311699
16321700 const S = struct {
16331701 fn doTheTest(comptime T: type, comptime s: T) !void {
......@@ -1658,6 +1726,7 @@ test "peer type resolution: float and comptime-known fixed-width integer" {
16581726 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16591727 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16601728 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1729 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16611730
16621731 const i: u8 = 100;
16631732 var f: f32 = 1.234;
......@@ -1680,6 +1749,7 @@ test "peer type resolution: same array type with sentinel" {
16801749 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16811750 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16821751 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1752 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16831753
16841754 var a: [2:0]u32 = .{ 0, 1 };
16851755 var b: [2:0]u32 = .{ 2, 3 };
......@@ -1702,6 +1772,7 @@ test "peer type resolution: array with sentinel and array without sentinel" {
17021772 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17031773 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17041774 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1775 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17051776
17061777 var a: [2:0]u32 = .{ 0, 1 };
17071778 var b: [2]u32 = .{ 2, 3 };
......@@ -1724,6 +1795,7 @@ test "peer type resolution: array and vector with same child type" {
17241795 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17251796 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17261797 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1798 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17271799
17281800 var arr: [2]u32 = .{ 0, 1 };
17291801 var vec: @Vector(2, u32) = .{ 2, 3 };
......@@ -1747,6 +1819,7 @@ test "peer type resolution: array with smaller child type and vector with larger
17471819 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17481820 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
17491821 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1822 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17501823
17511824 var arr: [2]u8 = .{ 0, 1 };
17521825 var vec: @Vector(2, u64) = .{ 2, 3 };
......@@ -1769,6 +1842,7 @@ test "peer type resolution: error union and optional of same type" {
17691842 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17701843 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17711844 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1845 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17721846
17731847 const E = error{Foo};
17741848 var a: E!*u8 = error.Foo;
......@@ -1792,6 +1866,7 @@ test "peer type resolution: C pointer and @TypeOf(null)" {
17921866 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17931867 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17941868 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1869 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17951870
17961871 var a: [*c]c_int = 0x1000;
17971872 _ = &a;
......@@ -1814,6 +1889,7 @@ test "peer type resolution: three-way resolution combines error set and optional
18141889 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18151890 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18161891 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1892 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18171893
18181894 const E = error{Foo};
18191895 var a: E = error.Foo;
......@@ -1858,6 +1934,7 @@ test "peer type resolution: vector and optional vector" {
18581934 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
18591935 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18601936 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
1937 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18611938
18621939 var a: ?@Vector(3, u32) = .{ 0, 1, 2 };
18631940 var b: @Vector(3, u32) = .{ 3, 4, 5 };
......@@ -1880,6 +1957,7 @@ test "peer type resolution: optional fixed-width int and comptime_int" {
18801957 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18811958 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18821959 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1960 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18831961
18841962 var a: ?i32 = 42;
18851963 _ = &a;
......@@ -1902,6 +1980,7 @@ test "peer type resolution: array and tuple" {
19021980 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
19031981 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19041982 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1983 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19051984
19061985 var arr: [3]i32 = .{ 1, 2, 3 };
19071986 _ = &arr;
......@@ -1926,6 +2005,7 @@ test "peer type resolution: vector and tuple" {
19262005 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19272006 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
19282007 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2008 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19292009
19302010 var vec: @Vector(3, i32) = .{ 1, 2, 3 };
19312011 _ = &vec;
......@@ -1950,6 +2030,7 @@ test "peer type resolution: vector and array and tuple" {
19502030 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19512031 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
19522032 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2033 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19532034
19542035 var vec: @Vector(2, i8) = .{ 10, 20 };
19552036 var arr: [2]i8 = .{ 30, 40 };
......@@ -2034,6 +2115,7 @@ test "peer type resolution: tuple pointer and optional slice" {
20342115 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
20352116 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
20362117 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2118 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20372119 // Miscompilation on Intel's OpenCL CPU runtime.
20382120 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
20392121
......@@ -2058,6 +2140,7 @@ test "peer type resolution: many compatible pointers" {
20582140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
20592141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
20602142 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
2143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20612144
20622145 var buf = "foo-3".*;
20632146
......@@ -2125,6 +2208,7 @@ test "peer type resolution: tuples with comptime fields" {
21252208 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21262209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
21272210 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
2211 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21282212
21292213 const a = .{ 1, 2 };
21302214 const b = .{ @as(u32, 3), @as(i16, 4) };
......@@ -2156,6 +2240,7 @@ test "peer type resolution: C pointer and many pointer" {
21562240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21572241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21582242 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2243 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21592244
21602245 var buf = "hello".*;
21612246
......@@ -2179,6 +2264,7 @@ test "peer type resolution: pointer attributes are combined correctly" {
21792264 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21802265 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21812266 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2267 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21822268
21832269 var buf_a align(4) = "foo".*;
21842270 var buf_b align(4) = "bar".*;
......@@ -2222,6 +2308,7 @@ test "peer type resolution: arrays of compatible types" {
22222308 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
22232309 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
22242310 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2311 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
22252312
22262313 var e0: u8 = 3;
22272314 var e1: u8 = 2;
......@@ -2239,6 +2326,7 @@ test "cast builtins can wrap result in optional" {
22392326 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
22402327 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
22412328 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2329 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
22422330
22432331 const S = struct {
22442332 const MyEnum = enum(u32) { _ };
......@@ -2276,6 +2364,7 @@ test "cast builtins can wrap result in error union" {
22762364 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
22772365 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
22782366 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2367 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
22792368
22802369 const S = struct {
22812370 const MyEnum = enum(u32) { _ };
......@@ -2314,6 +2403,7 @@ test "cast builtins can wrap result in error union and optional" {
23142403 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
23152404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23162405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2406 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23172407
23182408 const S = struct {
23192409 const MyEnum = enum(u32) { _ };
......@@ -2354,6 +2444,7 @@ test "@floatCast on vector" {
23542444 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23552445 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
23562446 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
2447 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23572448
23582449 const S = struct {
23592450 fn doTheTest() !void {
......@@ -2394,6 +2485,7 @@ test "@ptrFromInt on vector" {
23942485 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
23952486 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23962487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2488 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23972489
23982490 const S = struct {
23992491 fn doTheTest() !void {
......@@ -2417,6 +2509,7 @@ test "@intFromPtr on vector" {
24172509 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
24182510 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
24192511 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2512 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
24202513
24212514 const S = struct {
24222515 fn doTheTest() !void {
......@@ -2441,6 +2534,7 @@ test "@floatFromInt on vector" {
24412534 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
24422535 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24432536 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
2537 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
24442538
24452539 const S = struct {
24462540 fn doTheTest() !void {
......@@ -2460,6 +2554,7 @@ test "@intFromFloat on vector" {
24602554 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
24612555 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
24622556 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2557 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
24632558
24642559 const S = struct {
24652560 fn doTheTest() !void {
......@@ -2480,6 +2575,7 @@ test "@intFromBool on vector" {
24802575 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
24812576 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24822577 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2578 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
24832579
24842580 if (builtin.zig_backend == .stage2_llvm and
24852581 builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows)
......@@ -2503,6 +2599,7 @@ test "@intFromBool on vector" {
25032599
25042600test "numeric coercions with undefined" {
25052601 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
2602 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25062603
25072604 const from: i32 = undefined;
25082605 var to: f32 = from;
......@@ -2513,6 +2610,7 @@ test "numeric coercions with undefined" {
25132610
25142611test "15-bit int to float" {
25152612 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
2613 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25162614
25172615 var a: u15 = 42;
25182616 _ = &a;
......@@ -2525,6 +2623,7 @@ test "@as does not corrupt values with incompatible representations" {
25252623 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25262624 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25272625 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
2626 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25282627
25292628 const x: f32 = @as(f16, blk: {
25302629 if (false) {
......@@ -2540,6 +2639,7 @@ test "result information is preserved through many nested structures" {
25402639 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
25412640 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25422641 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2642 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25432643
25442644 const S = struct {
25452645 fn doTheTest() !void {
......@@ -2566,6 +2666,7 @@ test "@intCast vector of signed integer" {
25662666 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
25672667 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
25682668 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
2669 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25692670
25702671 var x: @Vector(4, i32) = .{ 1, 2, 3, 4 };
25712672 _ = &x;
......@@ -2586,6 +2687,7 @@ test "implicit cast from ptr to tuple to ptr to struct" {
25862687 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
25872688 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
25882689 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2690 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25892691
25902692 const ComptimeReason = union(enum) {
25912693 c_import: struct {
test/behavior/cast_int.zig+8
......@@ -9,6 +9,7 @@ test "@intCast i32 to u7" {
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1213
1314 var x: u128 = maxInt(u128);
1415 var y: i32 = 120;
......@@ -34,6 +35,8 @@ test "coerce i8 to i32 and @intCast back" {
3435}
3536
3637test "coerce non byte-sized integers accross 32bits boundary" {
38 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
39
3740 {
3841 var v: u21 = 6417;
3942 _ = &v;
......@@ -163,6 +166,8 @@ const Piece = packed struct {
163166};
164167
165168test "load non byte-sized optional value" {
169 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
170
166171 // Originally reported at https://github.com/ziglang/zig/issues/14200
167172 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
168173
......@@ -178,6 +183,8 @@ test "load non byte-sized optional value" {
178183}
179184
180185test "load non byte-sized value in struct" {
186 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
187
181188 if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO
182189 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
183190
......@@ -215,6 +222,7 @@ test "load non byte-sized value in union" {
215222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
216223 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
217224 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
225 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
218226
219227 // note: this bug is triggered by the == operator, expectEqual will hide it
220228 // using ptrCast not to depend on unitialised memory state
test/behavior/comptime_memory.zig+4
......@@ -408,6 +408,8 @@ test "mutate entire slice at comptime" {
408408}
409409
410410test "dereference undefined pointer to zero-bit type" {
411 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
412
411413 const p0: *void = undefined;
412414 try testing.expectEqual({}, p0.*);
413415
......@@ -513,5 +515,7 @@ fn fieldPtrTest() u32 {
513515 return a.value;
514516}
515517test "pointer in aggregate field can mutate comptime state" {
518 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
519
516520 try comptime std.testing.expect(fieldPtrTest() == 2);
517521}
test/behavior/const_slice_child.zig+1
......@@ -10,6 +10,7 @@ test "const slice child" {
1010 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1314
1415 const strs = [_][*]const u8{ "one", "two", "three" };
1516 argv = &strs;
test/behavior/defer.zig+5
......@@ -53,6 +53,7 @@ test "return variable while defer expression in scope to modify it" {
5353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5454 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
5555 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5657
5758 const S = struct {
5859 fn doTheTest() !void {
......@@ -94,6 +95,7 @@ test "mixing normal and error defers" {
9495 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9596 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9697 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9799
98100 try expect(runSomeErrorDefers(true) catch unreachable);
99101 try expect(result[0] == 'c');
......@@ -114,6 +116,7 @@ test "errdefer with payload" {
114116 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
115117 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
116118 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
119 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
117120
118121 const S = struct {
119122 fn foo() !i32 {
......@@ -136,6 +139,7 @@ test "reference to errdefer payload" {
136139 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
137140 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
138141 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
139143
140144 const S = struct {
141145 fn foo() !i32 {
......@@ -158,6 +162,7 @@ test "reference to errdefer payload" {
158162test "simple else prong doesn't emit an error for unreachable else prong" {
159163 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
160164 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
161166
162167 const S = struct {
163168 fn foo() error{Foo}!void {
test/behavior/destructure.zig+2
......@@ -23,6 +23,8 @@ test "simple destructure" {
2323}
2424
2525test "destructure with comptime syntax" {
26 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
27
2628 const S = struct {
2729 fn doTheTest() !void {
2830 {
test/behavior/duplicated_test_names.zig+1
......@@ -16,6 +16,7 @@ test "thingy" {}
1616
1717test thingy {
1818 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1920
2021 if (thingy(1, 2) != 3) unreachable;
2122}
test/behavior/empty_tuple_fields.zig+2
......@@ -5,6 +5,7 @@ test "empty file level struct" {
55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
89
910 const T = @import("empty_file_level_struct.zig");
1011 const info = @typeInfo(T);
......@@ -17,6 +18,7 @@ test "empty file level union" {
1718 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1819 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1920 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
21 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2022
2123 const T = @import("empty_file_level_union.zig");
2224 const info = @typeInfo(T);
test/behavior/empty_union.zig+4
......@@ -48,6 +48,8 @@ test "empty extern union" {
4848}
4949
5050test "empty union passed as argument" {
51 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
52
5153 const U = union(enum) {
5254 fn f(u: @This()) void {
5355 switch (u) {}
......@@ -57,6 +59,8 @@ test "empty union passed as argument" {
5759}
5860
5961test "empty enum passed as argument" {
62 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
63
6064 const E = enum {
6165 fn f(e: @This()) void {
6266 switch (e) {}
test/behavior/enum.zig+20
......@@ -610,6 +610,7 @@ fn testEnumWithSpecifiedTagValues(x: MultipleChoice) !void {
610610test "enum with specified tag values" {
611611 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
612612 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
613 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
613614
614615 try testEnumWithSpecifiedTagValues(MultipleChoice.C);
615616 try comptime testEnumWithSpecifiedTagValues(MultipleChoice.C);
......@@ -618,6 +619,7 @@ test "enum with specified tag values" {
618619test "non-exhaustive enum" {
619620 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
620621 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
622 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
621623
622624 const S = struct {
623625 const E = enum(u8) { a, b, _ };
......@@ -682,6 +684,7 @@ test "empty non-exhaustive enum" {
682684test "single field non-exhaustive enum" {
683685 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
684686 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
687 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
685688
686689 const S = struct {
687690 const E = enum(u8) { a, _ };
......@@ -746,6 +749,7 @@ test "cast integer literal to enum" {
746749test "enum with specified and unspecified tag values" {
747750 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
748751 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
752 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
749753
750754 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);
751755 try comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);
......@@ -854,6 +858,8 @@ fn doALoopThing(id: EnumWithOneMember) void {
854858}
855859
856860test "comparison operator on enum with one member is comptime-known" {
861 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
862
857863 doALoopThing(EnumWithOneMember.Eof);
858864}
859865
......@@ -907,6 +913,7 @@ test "enum literal casting to tagged union" {
907913 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
908914 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
909915 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
916 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910917
911918 const Arch = union(enum) {
912919 x86_64,
......@@ -933,6 +940,7 @@ const Bar = enum { A, B, C, D };
933940test "enum literal casting to error union with payload enum" {
934941 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
935942 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
943 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
936944
937945 var bar: error{B}!Bar = undefined;
938946 bar = .B; // should never cast to the error set
......@@ -944,6 +952,7 @@ test "constant enum initialization with differing sizes" {
944952 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
945953 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
946954 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
955 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
947956
948957 try test3_1(test3_foo);
949958 try test3_2(test3_bar);
......@@ -987,6 +996,7 @@ test "@tagName" {
987996 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
988997 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
989998 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
999 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9901000
9911001 try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
9921002 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
......@@ -1003,6 +1013,7 @@ test "@tagName non-exhaustive enum" {
10031013 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10041014 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10051015 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1016 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10061017
10071018 try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
10081019 comptime assert(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
......@@ -1014,6 +1025,7 @@ test "@tagName is null-terminated" {
10141025 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10151026 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10161027 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1028 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10171029
10181030 const S = struct {
10191031 fn doTheTest(n: BareNumber) !void {
......@@ -1029,6 +1041,7 @@ test "tag name with assigned enum values" {
10291041 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10301042 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10311043 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1044 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10321045
10331046 const LocalFoo = enum(u8) {
10341047 A = 1,
......@@ -1052,6 +1065,7 @@ test "tag name with signed enum values" {
10521065 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10531066 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10541067 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1068 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10551069
10561070 const LocalFoo = enum(isize) {
10571071 alfa = 62,
......@@ -1068,6 +1082,7 @@ test "enum literal casting to optional" {
10681082 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10691083 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10701084 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1085 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10711086
10721087 var bar: ?Bar = undefined;
10731088 bar = .B;
......@@ -1096,6 +1111,7 @@ test "bit field access with enum fields" {
10961111 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10971112 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10981113 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1114 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10991115
11001116 var data = bit_field_1;
11011117 try expect(getA(&data) == A.Two);
......@@ -1136,6 +1152,7 @@ test "tag name functions are unique" {
11361152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
11371153 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11381154 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1155 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11391156
11401157 {
11411158 const E = enum { a, b };
......@@ -1212,6 +1229,8 @@ test "enum tag from a local variable" {
12121229}
12131230
12141231test "auto-numbered enum with signed tag type" {
1232 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1233
12151234 const E = enum(i32) { a, b };
12161235
12171236 try std.testing.expectEqual(@as(i32, 0), @intFromEnum(E.a));
......@@ -1266,6 +1285,7 @@ test "matching captures causes enum equivalence" {
12661285
12671286test "large enum field values" {
12681287 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1288 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12691289
12701290 {
12711291 const E = enum(u64) { min = std.math.minInt(u64), max = std.math.maxInt(u64) };
test/behavior/error.zig+45
......@@ -31,6 +31,7 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
3131
3232test "error binary operator" {
3333 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
34 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3435
3536 const a = errBinaryOperatorG(true) catch 3;
3637 const b = errBinaryOperatorG(false) catch 3;
......@@ -62,12 +63,14 @@ pub fn baz() anyerror!i32 {
6263
6364test "error wrapping" {
6465 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
66 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6567
6668 try expect((baz() catch unreachable) == 15);
6769}
6870
6971test "unwrap simple value from error" {
7072 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
73 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7174
7275 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
7376 try expect(i == 13);
......@@ -78,6 +81,7 @@ fn unwrapSimpleValueFromErrorDo() anyerror!isize {
7881
7982test "error return in assignment" {
8083 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8185
8286 doErrReturnInAssignment() catch unreachable;
8387}
......@@ -100,6 +104,7 @@ test "syntax: optional operator in front of error union operator" {
100104test "widen cast integer payload of error union function call" {
101105 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
102106 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
103108
104109 const S = struct {
105110 fn errorable() !u64 {
......@@ -124,6 +129,7 @@ test "debug info for optional error set" {
124129
125130test "implicit cast to optional to error union to return result loc" {
126131 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
132 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
127133
128134 const S = struct {
129135 fn entry() !void {
......@@ -235,6 +241,8 @@ fn testExplicitErrorSetCast(set1: Set1) !void {
235241}
236242
237243test "@errorCast on error unions" {
244 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
245
238246 const S = struct {
239247 fn doTheTest() !void {
240248 {
......@@ -262,6 +270,7 @@ test "@errorCast on error unions" {
262270
263271test "comptime test error for empty error set" {
264272 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
273 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
265274
266275 try testComptimeTestErrorEmptySet(1234);
267276 try comptime testComptimeTestErrorEmptySet(1234);
......@@ -297,6 +306,8 @@ test "inferred empty error set comptime catch" {
297306}
298307
299308test "error inference with an empty set" {
309 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
310
300311 const S = struct {
301312 const Struct = struct {
302313 pub fn func() (error{})!usize {
......@@ -319,6 +330,7 @@ test "error inference with an empty set" {
319330
320331test "error union peer type resolution" {
321332 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
333 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
322334
323335 try testErrorUnionPeerTypeResolution(1);
324336}
......@@ -350,6 +362,7 @@ fn quux_1() !i32 {
350362
351363test "error: Zero sized error set returned with value payload crash" {
352364 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
365 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
353366
354367 _ = try foo3(0);
355368 _ = try comptime foo3(0);
......@@ -363,6 +376,7 @@ fn foo3(b: usize) Error!usize {
363376test "error: Infer error set from literals" {
364377 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
365378 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
379 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
366380
367381 _ = nullLiteral("n") catch |err| handleErrors(err);
368382 _ = floatLiteral("n") catch |err| handleErrors(err);
......@@ -402,6 +416,7 @@ test "nested error union function call in optional unwrap" {
402416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
403417 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
404418 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
419 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
405420
406421 const S = struct {
407422 const Foo = struct {
......@@ -448,6 +463,7 @@ test "nested error union function call in optional unwrap" {
448463test "return function call to error set from error union function" {
449464 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
450465 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
466 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
451467
452468 const S = struct {
453469 fn errorable() anyerror!i32 {
......@@ -466,6 +482,7 @@ test "optional error set is the same size as error set" {
466482 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
467483 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
468484 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
485 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
469486
470487 comptime assert(@sizeOf(?anyerror) == @sizeOf(anyerror));
471488 comptime assert(@alignOf(?anyerror) == @alignOf(anyerror));
......@@ -481,6 +498,7 @@ test "optional error set is the same size as error set" {
481498test "nested catch" {
482499 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
483500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
501 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
484502
485503 const S = struct {
486504 fn entry() !void {
......@@ -506,6 +524,7 @@ test "nested catch" {
506524test "function pointer with return type that is error union with payload which is pointer of parent struct" {
507525 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
508526 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
527 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
509528
510529 const S = struct {
511530 const Foo = struct {
......@@ -531,6 +550,7 @@ test "return result loc as peer result loc in inferred error set function" {
531550 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
532551 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
533552 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
553 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
534554
535555 const S = struct {
536556 fn doTheTest() !void {
......@@ -562,6 +582,7 @@ test "error payload type is correctly resolved" {
562582 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
563583 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
564584 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
585 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
565586
566587 const MyIntWrapper = struct {
567588 const Self = @This();
......@@ -592,6 +613,7 @@ test "@errorName" {
592613 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
593614 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
594615 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
616 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
595617
596618 try expect(mem.eql(u8, @errorName(error.AnError), "AnError"));
597619 try expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
......@@ -606,6 +628,7 @@ test "@errorName sentinel length matches slice length" {
606628 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
607629 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
608630 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
631 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
609632
610633 const name = testBuiltinErrorName(error.FooBar);
611634 const length: usize = 6;
......@@ -700,6 +723,7 @@ test "error union payload is properly aligned" {
700723 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
701724 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
702725 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
726 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
703727
704728 const S = struct {
705729 a: u128,
......@@ -731,6 +755,7 @@ test "ret_ptr doesn't cause own inferred error set to be resolved" {
731755
732756test "simple else prong allowed even when all errors handled" {
733757 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
758 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
734759
735760 const S = struct {
736761 fn foo() !u8 {
......@@ -759,6 +784,7 @@ test "pointer to error union payload" {
759784 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
760785 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
761786 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
787 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
762788
763789 var err_union: anyerror!u8 = 15;
764790
......@@ -792,6 +818,7 @@ test "error union of noreturn used with if" {
792818 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
793819 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
794820 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
821 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
795822
796823 NoReturn.a = 64;
797824 if (NoReturn.loop()) {
......@@ -806,6 +833,7 @@ test "error union of noreturn used with try" {
806833 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
807834 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
808835 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
836 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
809837
810838 NoReturn.a = 64;
811839 const err = NoReturn.testTry();
......@@ -817,6 +845,7 @@ test "error union of noreturn used with catch" {
817845 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
818846 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
819847 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
848 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
820849
821850 NoReturn.a = 64;
822851 const err = NoReturn.testCatch();
......@@ -828,6 +857,7 @@ test "alignment of wrapping an error union payload" {
828857 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
829858 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
830859 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
860 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
831861
832862 const S = struct {
833863 const I = extern struct { x: i128 };
......@@ -843,6 +873,7 @@ test "alignment of wrapping an error union payload" {
843873
844874test "compare error union and error set" {
845875 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
876 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
846877
847878 var a: anyerror = error.Foo;
848879 var b: anyerror!u32 = error.Bar;
......@@ -881,6 +912,7 @@ test "error from comptime string" {
881912 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
882913 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
883914 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
915 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
884916
885917 const name = "Weird error name!";
886918 const S = struct {
......@@ -904,6 +936,7 @@ test "field access of anyerror results in smaller error set" {
904936test "optional error union return type" {
905937 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
906938 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
939 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
907940
908941 const S = struct {
909942 fn foo() ?anyerror!u32 {
......@@ -918,6 +951,7 @@ test "optional error union return type" {
918951test "optional error set return type" {
919952 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
920953 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
954 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
921955
922956 const E = error{ A, B };
923957 const S = struct {
......@@ -931,6 +965,8 @@ test "optional error set return type" {
931965}
932966
933967test "optional error set function parameter" {
968 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
969
934970 const S = struct {
935971 fn doTheTest(a: ?anyerror) !void {
936972 try std.testing.expect(a.? == error.OutOfMemory);
......@@ -960,6 +996,7 @@ test "returning an error union containing a type with no runtime bits" {
960996test "try used in recursive function with inferred error set" {
961997 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
962998 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
999 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9631000
9641001 const Value = union(enum) {
9651002 values: []const @This(),
......@@ -1001,6 +1038,7 @@ test "function called at runtime is properly analyzed for inferred error set" {
10011038 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10021039 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10031040 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1041 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10041042
10051043 const S = struct {
10061044 fn foo() !void {
......@@ -1024,6 +1062,7 @@ test "generic type constructed from inferred error set of unresolved function" {
10241062 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10251063 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10261064 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1065 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10271066
10281067 const S = struct {
10291068 fn write(_: void, bytes: []const u8) !usize {
......@@ -1039,6 +1078,8 @@ test "generic type constructed from inferred error set of unresolved function" {
10391078}
10401079
10411080test "errorCast to adhoc inferred error set" {
1081 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1082
10421083 const S = struct {
10431084 inline fn baz() !i32 {
10441085 return @errorCast(err());
......@@ -1051,6 +1092,8 @@ test "errorCast to adhoc inferred error set" {
10511092}
10521093
10531094test "errorCast from error sets to error unions" {
1095 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1096
10541097 const err_union: Set1!void = @errorCast(error.A);
10551098 try expectError(error.A, err_union);
10561099}
......@@ -1059,6 +1102,7 @@ test "result location initialization of error union with OPV payload" {
10591102 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10601103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10611104 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1105 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10621106
10631107 const S = struct {
10641108 x: u0,
......@@ -1080,6 +1124,7 @@ test "result location initialization of error union with OPV payload" {
10801124
10811125test "return error union with i65" {
10821126 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10831128
10841129 try expect(try add(1000, 234) == 1234);
10851130}
test/behavior/eval.zig+30
......@@ -73,6 +73,7 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
7373test "constant expressions" {
7474 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7575 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7677
7778 var array: [array_size]u8 = undefined;
7879 _ = &array;
......@@ -142,6 +143,7 @@ test "pointer to type" {
142143test "a type constructed in a global expression" {
143144 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
144145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
146 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
145147
146148 var l: List = undefined;
147149 l.array[0] = 10;
......@@ -394,6 +396,7 @@ test "return 0 from function that has u0 return type" {
394396test "statically initialized struct" {
395397 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
396398 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
397400
398401 st_init_str_foo.x += 1;
399402 try expect(st_init_str_foo.x == 14);
......@@ -444,6 +447,7 @@ test "binary math operator in partially inlined function" {
444447 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
445448 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
446449 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
450 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
447451
448452 var s: [4]u32 = undefined;
449453 var b: [16]u8 = undefined;
......@@ -489,6 +493,7 @@ test "comptime bitwise operators" {
489493
490494test "comptime shlWithOverflow" {
491495 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
496 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
492497
493498 const ct_shifted = @shlWithOverflow(~@as(u64, 0), 16)[0];
494499 var a = ~@as(u64, 0);
......@@ -501,6 +506,7 @@ test "comptime shlWithOverflow" {
501506test "const ptr to variable data changes at runtime" {
502507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
503508 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
509 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
504510
505511 try expect(foo_ref.name[0] == 'a');
506512 foo_ref.name = "b";
......@@ -522,6 +528,7 @@ test "runtime 128 bit integer division" {
522528 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
523529 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
524530 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
531 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
525532
526533 var a: u128 = 152313999999999991610955792383;
527534 var b: u128 = 10000000000000000000;
......@@ -542,6 +549,7 @@ test "static eval list init" {
542549 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
543550 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
544551 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
552 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
545553
546554 try expect(static_vec3.data[2] == 1.0);
547555 try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
......@@ -713,6 +721,8 @@ fn loopNTimes(comptime n: usize) void {
713721}
714722
715723test "variable inside inline loop that has different types on different iterations" {
724 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
725
716726 try testVarInsideInlineLoop(.{ true, @as(u32, 42) });
717727}
718728
......@@ -736,6 +746,7 @@ test "array concatenation of function calls" {
736746 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
737747 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
738748 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
749 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
739750
740751 var a = oneItem(3) ++ oneItem(4);
741752 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 }));
......@@ -745,6 +756,7 @@ test "array multiplication of function calls" {
745756 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
746757 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
747758 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
759 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
748760
749761 var a = oneItem(3) ** scalar(2);
750762 try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 }));
......@@ -762,6 +774,7 @@ test "array concatenation peer resolves element types - value" {
762774 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
763775 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
764776 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
777 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
765778
766779 var a = [2]u3{ 1, 7 };
767780 var b = [3]u8{ 200, 225, 255 };
......@@ -779,6 +792,7 @@ test "array concatenation peer resolves element types - pointer" {
779792 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
780793 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
781794 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
795 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
782796
783797 var a = [2]u3{ 1, 7 };
784798 var b = [3]u8{ 200, 225, 255 };
......@@ -795,6 +809,7 @@ test "array concatenation sets the sentinel - value" {
795809 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
796810 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
797811 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
812 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
798813
799814 var a = [2]u3{ 1, 7 };
800815 var b = [3:69]u8{ 200, 225, 255 };
......@@ -813,6 +828,7 @@ test "array concatenation sets the sentinel - value" {
813828test "array concatenation sets the sentinel - pointer" {
814829 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
815830 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
831 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
816832
817833 var a = [2]u3{ 1, 7 };
818834 var b = [3:69]u8{ 200, 225, 255 };
......@@ -831,6 +847,7 @@ test "array multiplication sets the sentinel - value" {
831847 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
832848 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
833849 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
850 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
834851
835852 var a = [2:7]u3{ 1, 6 };
836853 _ = &a;
......@@ -848,6 +865,7 @@ test "array multiplication sets the sentinel - pointer" {
848865 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
849866 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
850867 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
868 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
851869
852870 var a = [2:7]u3{ 1, 6 };
853871 const b = &a ** 2;
......@@ -1070,6 +1088,7 @@ test "comptime break operand passing through runtime condition converted to runt
10701088test "comptime break operand passing through runtime switch converted to runtime break" {
10711089 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10721090 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1091 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10731092
10741093 const S = struct {
10751094 fn doTheTest(runtime: u8) !void {
......@@ -1090,6 +1109,7 @@ test "comptime break operand passing through runtime switch converted to runtime
10901109test "no dependency loop for alignment of self struct" {
10911110 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10921111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1112 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10931113
10941114 const S = struct {
10951115 fn doTheTest() !void {
......@@ -1127,6 +1147,7 @@ test "no dependency loop for alignment of self struct" {
11271147test "no dependency loop for alignment of self bare union" {
11281148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11291149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1150 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11301151
11311152 const S = struct {
11321153 fn doTheTest() !void {
......@@ -1164,6 +1185,7 @@ test "no dependency loop for alignment of self bare union" {
11641185test "no dependency loop for alignment of self tagged union" {
11651186 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11661187 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1188 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11671189
11681190 const S = struct {
11691191 fn doTheTest() !void {
......@@ -1354,6 +1376,7 @@ test "lazy value is resolved as slice operand" {
13541376 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13551377 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13561378 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1379 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13571380
13581381 const A = struct { a: u32 };
13591382 var a: [512]u64 = undefined;
......@@ -1533,6 +1556,7 @@ test "non-optional and optional array elements concatenated" {
15331556 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15341557 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15351558 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1559 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15361560
15371561 const array = [1]u8{'A'} ++ [1]?u8{null};
15381562 var index: usize = 0;
......@@ -1607,6 +1631,8 @@ test "struct in comptime false branch is not evaluated" {
16071631}
16081632
16091633test "result of nested switch assigned to variable" {
1634 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1635
16101636 var zds: u32 = 0;
16111637 zds = switch (zds) {
16121638 0 => switch (zds) {
......@@ -1621,6 +1647,8 @@ test "result of nested switch assigned to variable" {
16211647}
16221648
16231649test "inline for loop of functions returning error unions" {
1650 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1651
16241652 const T1 = struct {
16251653 fn v() error{}!usize {
16261654 return 1;
......@@ -1639,6 +1667,8 @@ test "inline for loop of functions returning error unions" {
16391667}
16401668
16411669test "if inside a switch" {
1670 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1671
16421672 var condition = true;
16431673 var wave_type: u32 = 0;
16441674 _ = .{ &condition, &wave_type };
test/behavior/export_builtin.zig+2
......@@ -48,6 +48,7 @@ test "exporting using field access" {
4848test "exporting comptime-known value" {
4949 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
5050 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
51 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5152 if (builtin.zig_backend == .stage2_x86_64 and
5253 (builtin.target.ofmt != .elf and
5354 builtin.target.ofmt != .macho and
......@@ -67,6 +68,7 @@ test "exporting comptime-known value" {
6768test "exporting comptime var" {
6869 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
6970 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7072 if (builtin.zig_backend == .stage2_x86_64 and
7173 (builtin.target.ofmt != .elf and
7274 builtin.target.ofmt != .macho and
test/behavior/export_keyword.zig+2
......@@ -9,6 +9,8 @@ const builtin = @import("builtin");
99// and generates code
1010const vram = @as([*]volatile u8, @ptrFromInt(0x20000000))[0..0x8000];
1111export fn writeToVRam() void {
12 if (builtin.zig_backend == .stage2_riscv64) return;
13
1214 vram[0] = 'X';
1315}
1416
test/behavior/extern.zig+3
......@@ -7,6 +7,7 @@ test "anyopaque extern symbol" {
77 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
88 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011
1112 const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" });
1213 const b: *i32 = @alignCast(@ptrCast(a));
......@@ -19,6 +20,7 @@ test "function extern symbol" {
1920 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
2021 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
2122 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2224
2325 const a = @extern(*const fn () callconv(.C) i32, .{ .name = "a_mystery_function" });
2426 try expect(a() == 4567);
......@@ -32,6 +34,7 @@ test "function extern symbol matches extern decl" {
3234 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
3335 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
3436 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
37 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3538
3639 const S = struct {
3740 extern fn another_mystery_function() u32;
test/behavior/field_parent_ptr.zig+21
......@@ -2,6 +2,8 @@ const expect = @import("std").testing.expect;
22const builtin = @import("builtin");
33
44test "@fieldParentPtr struct" {
5 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6
57 const C = struct {
68 a: bool = true,
79 b: f32 = 3.14,
......@@ -135,6 +137,8 @@ test "@fieldParentPtr struct" {
135137}
136138
137139test "@fieldParentPtr extern struct" {
140 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
141
138142 const C = extern struct {
139143 a: bool = true,
140144 b: f32 = 3.14,
......@@ -269,6 +273,7 @@ test "@fieldParentPtr extern struct" {
269273
270274test "@fieldParentPtr extern struct first zero-bit field" {
271275 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
276 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
272277
273278 const C = extern struct {
274279 a: u0 = 0,
......@@ -372,6 +377,7 @@ test "@fieldParentPtr extern struct first zero-bit field" {
372377
373378test "@fieldParentPtr extern struct middle zero-bit field" {
374379 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
380 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
375381
376382 const C = extern struct {
377383 a: f32 = 3.14,
......@@ -475,6 +481,7 @@ test "@fieldParentPtr extern struct middle zero-bit field" {
475481
476482test "@fieldParentPtr extern struct last zero-bit field" {
477483 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
484 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
478485
479486 const C = extern struct {
480487 a: f32 = 3.14,
......@@ -581,6 +588,7 @@ test "@fieldParentPtr unaligned packed struct" {
581588 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
582589 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
583590 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
591 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
584592
585593 const C = packed struct {
586594 a: bool = true,
......@@ -719,6 +727,7 @@ test "@fieldParentPtr aligned packed struct" {
719727 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
720728 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
721729 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
730 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
722731
723732 const C = packed struct {
724733 a: f32 = 3.14,
......@@ -856,6 +865,7 @@ test "@fieldParentPtr nested packed struct" {
856865 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
857866 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
858867 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
868 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
859869
860870 {
861871 const C = packed struct {
......@@ -1018,6 +1028,7 @@ test "@fieldParentPtr packed struct first zero-bit field" {
10181028 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
10191029 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10201030 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1031 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10211032
10221033 const C = packed struct {
10231034 a: u0 = 0,
......@@ -1123,6 +1134,7 @@ test "@fieldParentPtr packed struct middle zero-bit field" {
11231134 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
11241135 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
11251136 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1137 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11261138
11271139 const C = packed struct {
11281140 a: f32 = 3.14,
......@@ -1228,6 +1240,7 @@ test "@fieldParentPtr packed struct last zero-bit field" {
12281240 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
12291241 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
12301242 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1243 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12311244
12321245 const C = packed struct {
12331246 a: f32 = 3.14,
......@@ -1330,6 +1343,8 @@ test "@fieldParentPtr packed struct last zero-bit field" {
13301343}
13311344
13321345test "@fieldParentPtr tagged union" {
1346 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1347
13331348 const C = union(enum) {
13341349 a: bool,
13351350 b: f32,
......@@ -1463,6 +1478,8 @@ test "@fieldParentPtr tagged union" {
14631478}
14641479
14651480test "@fieldParentPtr untagged union" {
1481 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1482
14661483 const C = union {
14671484 a: bool,
14681485 b: f32,
......@@ -1596,6 +1613,8 @@ test "@fieldParentPtr untagged union" {
15961613}
15971614
15981615test "@fieldParentPtr extern union" {
1616 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1617
15991618 const C = extern union {
16001619 a: bool,
16011620 b: f32,
......@@ -1731,6 +1750,7 @@ test "@fieldParentPtr extern union" {
17311750test "@fieldParentPtr packed union" {
17321751 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
17331752 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1753 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17341754 if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // TODO
17351755
17361756 const C = packed union {
......@@ -1868,6 +1888,7 @@ test "@fieldParentPtr packed union" {
18681888test "@fieldParentPtr tagged union all zero-bit fields" {
18691889 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
18701890 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1891 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18711892
18721893 const C = union(enum) {
18731894 a: u0,
test/behavior/floatop.zig+78
......@@ -15,12 +15,15 @@ fn epsForType(comptime T: type) T {
1515
1616test "add f16" {
1717 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1819
1920 try testAdd(f16);
2021 try comptime testAdd(f16);
2122}
2223
2324test "add f32/f64" {
25 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
26
2427 try testAdd(f32);
2528 try comptime testAdd(f32);
2629 try testAdd(f64);
......@@ -30,6 +33,7 @@ test "add f32/f64" {
3033test "add f80/f128/c_longdouble" {
3134 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
3235 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
36 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3337
3438 try testAdd(f80);
3539 try comptime testAdd(f80);
......@@ -49,12 +53,15 @@ fn testAdd(comptime T: type) !void {
4953
5054test "sub f16" {
5155 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
56 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5257
5358 try testSub(f16);
5459 try comptime testSub(f16);
5560}
5661
5762test "sub f32/f64" {
63 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
64
5865 try testSub(f32);
5966 try comptime testSub(f32);
6067 try testSub(f64);
......@@ -64,6 +71,7 @@ test "sub f32/f64" {
6471test "sub f80/f128/c_longdouble" {
6572 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
6673 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
74 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6775
6876 try testSub(f80);
6977 try comptime testSub(f80);
......@@ -83,12 +91,15 @@ fn testSub(comptime T: type) !void {
8391
8492test "mul f16" {
8593 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
94 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8695
8796 try testMul(f16);
8897 try comptime testMul(f16);
8998}
9099
91100test "mul f32/f64" {
101 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
102
92103 try testMul(f32);
93104 try comptime testMul(f32);
94105 try testMul(f64);
......@@ -98,6 +109,7 @@ test "mul f32/f64" {
98109test "mul f80/f128/c_longdouble" {
99110 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
100111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
101113
102114 try testMul(f80);
103115 try comptime testMul(f80);
......@@ -119,6 +131,7 @@ test "cmp f16" {
119131 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
120132 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
121133 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
134 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
122135
123136 try testCmp(f16);
124137 try comptime testCmp(f16);
......@@ -127,6 +140,7 @@ test "cmp f16" {
127140test "cmp f32/f64" {
128141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
129142 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
130144
131145 try testCmp(f32);
132146 try comptime testCmp(f32);
......@@ -140,6 +154,7 @@ test "cmp f128" {
140154 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
141155 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
142156 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
157 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
143158
144159 try testCmp(f128);
145160 try comptime testCmp(f128);
......@@ -213,6 +228,7 @@ test "different sized float comparisons" {
213228 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
214229 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
215230 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
231 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
216232
217233 try testDifferentSizedFloatComparisons();
218234 try comptime testDifferentSizedFloatComparisons();
......@@ -261,6 +277,7 @@ test "@sqrt f16" {
261277 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
262278 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
263279 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
280 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
264281
265282 try testSqrt(f16);
266283 try comptime testSqrt(f16);
......@@ -272,6 +289,7 @@ test "@sqrt f32/f64" {
272289 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
273290 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
274291 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
292 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
275293
276294 try testSqrt(f32);
277295 try comptime testSqrt(f32);
......@@ -285,6 +303,7 @@ test "@sqrt f80/f128/c_longdouble" {
285303 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
286304 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
287305 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
306 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
288307
289308 if (builtin.os.tag == .freebsd) {
290309 // TODO https://github.com/ziglang/zig/issues/10875
......@@ -371,6 +390,7 @@ test "@sqrt with vectors" {
371390 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
372391 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
373392 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
393 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
374394
375395 try testSqrtWithVectors();
376396 try comptime testSqrtWithVectors();
......@@ -392,6 +412,7 @@ test "@sin f16" {
392412 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
393413 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
394414 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
415 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
395416
396417 try testSin(f16);
397418 try comptime testSin(f16);
......@@ -403,6 +424,7 @@ test "@sin f32/f64" {
403424 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
404425 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
405426 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
427 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
406428
407429 try testSin(f32);
408430 comptime try testSin(f32);
......@@ -416,6 +438,7 @@ test "@sin f80/f128/c_longdouble" {
416438 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
417439 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
418440 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
441 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
419442
420443 try testSin(f80);
421444 comptime try testSin(f80);
......@@ -443,6 +466,7 @@ test "@sin with vectors" {
443466 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
444467 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
445468 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
469 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
446470
447471 try testSinWithVectors();
448472 try comptime testSinWithVectors();
......@@ -464,6 +488,7 @@ test "@cos f16" {
464488 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
465489 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
466490 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
491 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
467492
468493 try testCos(f16);
469494 try comptime testCos(f16);
......@@ -475,6 +500,7 @@ test "@cos f32/f64" {
475500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
476501 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
477502 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
503 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
478504
479505 try testCos(f32);
480506 try comptime testCos(f32);
......@@ -488,6 +514,7 @@ test "@cos f80/f128/c_longdouble" {
488514 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
489515 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
490516 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
517 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
491518
492519 try testCos(f80);
493520 try comptime testCos(f80);
......@@ -515,6 +542,7 @@ test "@cos with vectors" {
515542 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
516543 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
517544 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
545 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
518546
519547 try testCosWithVectors();
520548 try comptime testCosWithVectors();
......@@ -536,6 +564,7 @@ test "@tan f16" {
536564 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
537565 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
538566 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
567 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
539568
540569 try testTan(f16);
541570 try comptime testTan(f16);
......@@ -547,6 +576,7 @@ test "@tan f32/f64" {
547576 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
548577 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
549578 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
579 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
550580
551581 try testTan(f32);
552582 try comptime testTan(f32);
......@@ -560,6 +590,7 @@ test "@tan f80/f128/c_longdouble" {
560590 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
561591 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
562592 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
593 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
563594
564595 try testTan(f80);
565596 try comptime testTan(f80);
......@@ -587,6 +618,7 @@ test "@tan with vectors" {
587618 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
588619 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
589620 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
621 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
590622
591623 try testTanWithVectors();
592624 try comptime testTanWithVectors();
......@@ -608,6 +640,7 @@ test "@exp f16" {
608640 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
609641 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
610642 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
643 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
611644
612645 try testExp(f16);
613646 try comptime testExp(f16);
......@@ -619,6 +652,7 @@ test "@exp f32/f64" {
619652 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
620653 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
621654 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
655 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
622656
623657 try testExp(f32);
624658 try comptime testExp(f32);
......@@ -632,6 +666,7 @@ test "@exp f80/f128/c_longdouble" {
632666 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
633667 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
634668 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
669 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
635670
636671 try testExp(f80);
637672 try comptime testExp(f80);
......@@ -663,6 +698,7 @@ test "@exp with vectors" {
663698 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
664699 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
665700 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
701 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
666702
667703 try testExpWithVectors();
668704 try comptime testExpWithVectors();
......@@ -684,6 +720,7 @@ test "@exp2 f16" {
684720 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
685721 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
686722 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
723 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
687724
688725 try testExp2(f16);
689726 try comptime testExp2(f16);
......@@ -695,6 +732,7 @@ test "@exp2 f32/f64" {
695732 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
696733 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
697734 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
735 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
698736
699737 try testExp2(f32);
700738 try comptime testExp2(f32);
......@@ -708,6 +746,7 @@ test "@exp2 f80/f128/c_longdouble" {
708746 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
709747 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
710748 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
749 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
711750
712751 try testExp2(f80);
713752 try comptime testExp2(f80);
......@@ -734,6 +773,7 @@ test "@exp2 with @vectors" {
734773 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
735774 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
736775 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
776 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
737777
738778 try testExp2WithVectors();
739779 try comptime testExp2WithVectors();
......@@ -755,6 +795,7 @@ test "@log f16" {
755795 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
756796 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
757797 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
798 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
758799
759800 try testLog(f16);
760801 try comptime testLog(f16);
......@@ -766,6 +807,7 @@ test "@log f32/f64" {
766807 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
767808 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
768809 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
810 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
769811
770812 try testLog(f32);
771813 try comptime testLog(f32);
......@@ -779,6 +821,7 @@ test "@log f80/f128/c_longdouble" {
779821 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
780822 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
781823 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
824 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
782825
783826 try testLog(f80);
784827 try comptime testLog(f80);
......@@ -806,6 +849,7 @@ test "@log with @vectors" {
806849 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
807850 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
808851 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
852 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
809853
810854 {
811855 var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
......@@ -824,6 +868,7 @@ test "@log2 f16" {
824868 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
825869 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
826870 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
871 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
827872
828873 try testLog2(f16);
829874 try comptime testLog2(f16);
......@@ -835,6 +880,7 @@ test "@log2 f32/f64" {
835880 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
836881 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
837882 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
883 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
838884
839885 try testLog2(f32);
840886 try comptime testLog2(f32);
......@@ -848,6 +894,7 @@ test "@log2 f80/f128/c_longdouble" {
848894 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
849895 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
850896 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
897 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
851898
852899 try testLog2(f80);
853900 try comptime testLog2(f80);
......@@ -873,6 +920,7 @@ test "@log2 with vectors" {
873920 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
874921 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
875922 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
923 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
876924 // https://github.com/ziglang/zig/issues/13681
877925 if (builtin.zig_backend == .stage2_llvm and
878926 builtin.cpu.arch == .aarch64 and
......@@ -899,6 +947,7 @@ test "@log10 f16" {
899947 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
900948 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
901949 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
950 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
902951
903952 try testLog10(f16);
904953 try comptime testLog10(f16);
......@@ -910,6 +959,7 @@ test "@log10 f32/f64" {
910959 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
911960 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
912961 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
962 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
913963
914964 try testLog10(f32);
915965 try comptime testLog10(f32);
......@@ -923,6 +973,7 @@ test "@log10 f80/f128/c_longdouble" {
923973 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
924974 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
925975 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
976 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
926977
927978 try testLog10(f80);
928979 try comptime testLog10(f80);
......@@ -949,6 +1000,7 @@ test "@log10 with vectors" {
9491000 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9501001 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9511002 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1003 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9521004
9531005 try testLog10WithVectors();
9541006 try comptime testLog10WithVectors();
......@@ -969,6 +1021,7 @@ test "@abs f16" {
9691021 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9701022 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9711023 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1024 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9721025
9731026 try testFabs(f16);
9741027 try comptime testFabs(f16);
......@@ -978,6 +1031,7 @@ test "@abs f32/f64" {
9781031 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9791032 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9801033 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1034 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9811035
9821036 try testFabs(f32);
9831037 try comptime testFabs(f32);
......@@ -992,6 +1046,7 @@ test "@abs f80/f128/c_longdouble" {
9921046 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9931047 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
9941048 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1049 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9951050
9961051 try testFabs(f80);
9971052 try comptime testFabs(f80);
......@@ -1069,6 +1124,7 @@ test "@abs with vectors" {
10691124 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10701125 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10711126 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10721128
10731129 try testFabsWithVectors();
10741130 try comptime testFabsWithVectors();
......@@ -1089,6 +1145,7 @@ test "@floor f16" {
10891145 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10901146 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10911147 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1148 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10921149
10931150 try testFloor(f16);
10941151 try comptime testFloor(f16);
......@@ -1099,6 +1156,7 @@ test "@floor f32/f64" {
10991156 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11001157 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11011158 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1159 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11021160
11031161 try testFloor(f32);
11041162 try comptime testFloor(f32);
......@@ -1113,6 +1171,7 @@ test "@floor f80/f128/c_longdouble" {
11131171 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11141172 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
11151173 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1174 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11161175
11171176 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
11181177 // https://github.com/ziglang/zig/issues/12602
......@@ -1161,6 +1220,7 @@ test "@floor with vectors" {
11611220 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11621221 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11631222 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1223 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11641224 if (builtin.zig_backend == .stage2_x86_64 and
11651225 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
11661226
......@@ -1184,6 +1244,7 @@ test "@ceil f16" {
11841244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11851245 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
11861246 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1247 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11871248
11881249 try testCeil(f16);
11891250 try comptime testCeil(f16);
......@@ -1195,6 +1256,7 @@ test "@ceil f32/f64" {
11951256 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11961257 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
11971258 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1259 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11981260
11991261 try testCeil(f32);
12001262 try comptime testCeil(f32);
......@@ -1209,6 +1271,7 @@ test "@ceil f80/f128/c_longdouble" {
12091271 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12101272 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
12111273 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1274 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12121275
12131276 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
12141277 // https://github.com/ziglang/zig/issues/12602
......@@ -1258,6 +1321,7 @@ test "@ceil with vectors" {
12581321 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12591322 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
12601323 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1324 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12611325 if (builtin.zig_backend == .stage2_x86_64 and
12621326 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
12631327
......@@ -1281,6 +1345,7 @@ test "@trunc f16" {
12811345 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12821346 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
12831347 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1348 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12841349
12851350 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
12861351 // https://github.com/ziglang/zig/issues/16846
......@@ -1297,6 +1362,7 @@ test "@trunc f32/f64" {
12971362 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12981363 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
12991364 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1365 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13001366
13011367 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
13021368 // https://github.com/ziglang/zig/issues/16846
......@@ -1316,6 +1382,7 @@ test "@trunc f80/f128/c_longdouble" {
13161382 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13171383 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
13181384 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1385 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13191386
13201387 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
13211388 // https://github.com/ziglang/zig/issues/12602
......@@ -1365,6 +1432,7 @@ test "@trunc with vectors" {
13651432 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13661433 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13671434 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1435 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13681436 if (builtin.zig_backend == .stage2_x86_64 and
13691437 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
13701438
......@@ -1389,6 +1457,7 @@ test "neg f16" {
13891457 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13901458 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
13911459 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1460 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13921461
13931462 if (builtin.os.tag == .freebsd) {
13941463 // TODO file issue to track this failure
......@@ -1405,6 +1474,7 @@ test "neg f32/f64" {
14051474 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14061475 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14071476 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1477 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14081478
14091479 try testNeg(f32);
14101480 try comptime testNeg(f32);
......@@ -1419,6 +1489,7 @@ test "neg f80/f128/c_longdouble" {
14191489 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14201490 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
14211491 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1492 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14221493
14231494 try testNeg(f80);
14241495 try comptime testNeg(f80);
......@@ -1525,6 +1596,7 @@ test "comptime fixed-width float zero divided by zero produces NaN" {
15251596 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15261597 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15271598 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1599 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15281600
15291601 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
15301602 try expect(math.isNan(@as(F, 0) / @as(F, 0)));
......@@ -1584,6 +1656,7 @@ test "comptime inf >= runtime 1" {
15841656test "comptime isNan(nan * 1)" {
15851657 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15861658 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1659 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15871660
15881661 const nan_times_one = comptime std.math.nan(f64) * 1;
15891662 try std.testing.expect(std.math.isNan(nan_times_one));
......@@ -1591,6 +1664,7 @@ test "comptime isNan(nan * 1)" {
15911664test "runtime isNan(nan * 1)" {
15921665 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15931666 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1667 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15941668
15951669 const nan_times_one = std.math.nan(f64) * 1;
15961670 try std.testing.expect(std.math.isNan(nan_times_one));
......@@ -1598,6 +1672,7 @@ test "runtime isNan(nan * 1)" {
15981672test "comptime isNan(nan * 0)" {
15991673 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16001674 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1675 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16011676
16021677 const nan_times_zero = comptime std.math.nan(f64) * 0;
16031678 try std.testing.expect(std.math.isNan(nan_times_zero));
......@@ -1607,6 +1682,7 @@ test "comptime isNan(nan * 0)" {
16071682test "runtime isNan(nan * 0)" {
16081683 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16091684 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1685 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16101686
16111687 const nan_times_zero = std.math.nan(f64) * 0;
16121688 try std.testing.expect(std.math.isNan(nan_times_zero));
......@@ -1616,6 +1692,7 @@ test "runtime isNan(nan * 0)" {
16161692test "comptime isNan(inf * 0)" {
16171693 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16181694 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1695 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16191696
16201697 const inf_times_zero = comptime std.math.inf(f64) * 0;
16211698 try std.testing.expect(std.math.isNan(inf_times_zero));
......@@ -1625,6 +1702,7 @@ test "comptime isNan(inf * 0)" {
16251702test "runtime isNan(inf * 0)" {
16261703 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16271704 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1705 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16281706
16291707 const inf_times_zero = std.math.inf(f64) * 0;
16301708 try std.testing.expect(std.math.isNan(inf_times_zero));
test/behavior/fn.zig+22
......@@ -71,6 +71,7 @@ fn outer(y: u32) *const fn (u32) u32 {
7171
7272test "return inner function which references comptime variable of outer function" {
7373 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
74 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7475
7576 const func = outer(10);
7677 try expect(func(3) == 7);
......@@ -80,6 +81,7 @@ test "discard the result of a function that returns a struct" {
8081 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
8283 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8385
8486 const S = struct {
8587 fn entry() void {
......@@ -104,6 +106,7 @@ test "inline function call that calls optional function pointer, return pointer
104106 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
105107 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
106108 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
107110
108111 const S = struct {
109112 field: u32,
......@@ -181,12 +184,14 @@ test "function with complex callconv and return type expressions" {
181184 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
182185 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
183186 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
187 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
184188
185189 try expect(fComplexCallconvRet(3).x == 9);
186190}
187191
188192test "pass by non-copying value" {
189193 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
190195
191196 try expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
192197}
......@@ -202,6 +207,7 @@ fn addPointCoords(pt: Point) i32 {
202207
203208test "pass by non-copying value through var arg" {
204209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
210 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
205211
206212 try expect((try addPointCoordsVar(Point{ .x = 1, .y = 2 })) == 3);
207213}
......@@ -213,6 +219,7 @@ fn addPointCoordsVar(pt: anytype) !i32 {
213219
214220test "pass by non-copying value as method" {
215221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
216223
217224 var pt = Point2{ .x = 1, .y = 2 };
218225 try expect(pt.addPointCoords() == 3);
......@@ -229,6 +236,7 @@ const Point2 = struct {
229236
230237test "pass by non-copying value as method, which is generic" {
231238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
232240
233241 var pt = Point3{ .x = 1, .y = 2 };
234242 try expect(pt.addPointCoords(i32) == 3);
......@@ -257,6 +265,7 @@ test "implicit cast fn call result to optional in field result" {
257265 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
258266 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
259267 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
268 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
260269
261270 const S = struct {
262271 fn entry() !void {
......@@ -283,6 +292,7 @@ test "implicit cast fn call result to optional in field result" {
283292test "void parameters" {
284293 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
285294 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
295 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
286296
287297 try voidFun(1, void{}, 2, {});
288298}
......@@ -346,6 +356,7 @@ test "function call with anon list literal" {
346356 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
347357 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
348358 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
359 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
349360
350361 const S = struct {
351362 fn doTheTest() !void {
......@@ -366,6 +377,7 @@ test "function call with anon list literal - 2D" {
366377 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
367378 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
368379 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
380 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
369381
370382 const S = struct {
371383 fn doTheTest() !void {
......@@ -402,6 +414,8 @@ test "ability to give comptime types and non comptime types to same parameter" {
402414}
403415
404416test "function with inferred error set but returning no error" {
417 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
418
405419 const S = struct {
406420 fn foo() !void {}
407421 };
......@@ -412,6 +426,7 @@ test "function with inferred error set but returning no error" {
412426
413427test "import passed byref to function in return type" {
414428 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
429 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
415430
416431 const S = struct {
417432 fn get() @import("std").ArrayListUnmanaged(i32) {
......@@ -429,6 +444,7 @@ test "implicit cast function to function ptr" {
429444 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
430445 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
431446 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
447 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
432448
433449 const S1 = struct {
434450 export fn someFunctionThatReturnsAValue() c_int {
......@@ -449,6 +465,7 @@ test "implicit cast function to function ptr" {
449465test "method call with optional and error union first param" {
450466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
451467 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
468 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
452469
453470 const S = struct {
454471 x: i32 = 1234,
......@@ -468,6 +485,7 @@ test "method call with optional and error union first param" {
468485test "method call with optional pointer first param" {
469486 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
470487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
488 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
471489
472490 const S = struct {
473491 x: i32 = 1234,
......@@ -487,6 +505,7 @@ test "using @ptrCast on function pointers" {
487505 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
488506 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
489507 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
508 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
490509
491510 const S = struct {
492511 const A = struct { data: [4]u8 };
......@@ -524,6 +543,7 @@ test "function returns function returning type" {
524543
525544test "peer type resolution of inferred error set with non-void payload" {
526545 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
546 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
527547
528548 const S = struct {
529549 fn openDataFile(mode: enum { read, write }) !u32 {
......@@ -566,6 +586,8 @@ test "lazy values passed to anytype parameter" {
566586}
567587
568588test "pass and return comptime-only types" {
589 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
590
569591 const S = struct {
570592 fn returnNull(comptime x: @Type(.Null)) @Type(.Null) {
571593 return x;
test/behavior/fn_delegation.zig+1
......@@ -34,6 +34,7 @@ fn custom(comptime T: type, comptime num: u64) fn (T) u64 {
3434test "fn delegation" {
3535 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
3636 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3738
3839 const foo = Foo{};
3940 try expect(foo.one() == 11);
test/behavior/for.zig+18
......@@ -69,6 +69,7 @@ test "basic for loop" {
6969 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7070 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7171 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7273
7374 const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3;
7475
......@@ -112,6 +113,7 @@ test "for with null and T peer types and inferred result location type" {
112113 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
113114 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
114115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
116 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
115117
116118 const S = struct {
117119 fn doTheTest(slice: []const u8) !void {
......@@ -132,6 +134,7 @@ test "for with null and T peer types and inferred result location type" {
132134test "2 break statements and an else" {
133135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
134136 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
135138
136139 const S = struct {
137140 fn entry(t: bool, f: bool) !void {
......@@ -153,6 +156,7 @@ test "for loop with pointer elem var" {
153156 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
154157 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
155158 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
159 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
156160
157161 const source = "abcdefg";
158162 var target: [source.len]u8 = undefined;
......@@ -179,6 +183,7 @@ fn mangleString(s: []u8) void {
179183test "for copies its payload" {
180184 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
181185 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
186 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
182187
183188 const S = struct {
184189 fn doTheTest() !void {
......@@ -198,6 +203,7 @@ test "for on slice with allowzero ptr" {
198203 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
199204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
200205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
201207
202208 const S = struct {
203209 fn doTheTest(slice: []const u8) !void {
......@@ -213,6 +219,7 @@ test "for on slice with allowzero ptr" {
213219test "else continue outer for" {
214220 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
215221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
216223
217224 var i: usize = 6;
218225 var buf: [5]u8 = undefined;
......@@ -226,6 +233,7 @@ test "else continue outer for" {
226233
227234test "for loop with else branch" {
228235 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
236 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
229237
230238 {
231239 var x = [_]u32{ 1, 2 };
......@@ -275,6 +283,7 @@ test "two counters" {
275283test "1-based counter and ptr to array" {
276284 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
277285 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
286 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
278287
279288 var ok: usize = 0;
280289
......@@ -308,6 +317,7 @@ test "slice and two counters, one is offset and one is runtime" {
308317 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
309318 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
310319 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
311321
312322 const slice: []const u8 = "blah";
313323 var start: usize = 0;
......@@ -337,6 +347,7 @@ test "two slices, one captured by-ref" {
337347 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
338348 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
339349 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
350 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
340351
341352 var buf: [10]u8 = undefined;
342353 const slice1: []const u8 = "blah";
......@@ -356,6 +367,7 @@ test "raw pointer and slice" {
356367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
357368 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
358369 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
370 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
359371
360372 var buf: [10]u8 = undefined;
361373 const slice: []const u8 = "blah";
......@@ -375,6 +387,7 @@ test "raw pointer and counter" {
375387 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
376388 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
377389 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
390 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
378391
379392 var buf: [10]u8 = undefined;
380393 const ptr: [*]u8 = &buf;
......@@ -393,6 +406,7 @@ test "inline for with slice as the comptime-known" {
393406 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
394407 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
395408 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
396410
397411 const comptime_slice = "hello";
398412 var runtime_i: usize = 3;
......@@ -424,6 +438,7 @@ test "inline for with counter as the comptime-known" {
424438 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
425439 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
426440 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
441 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
427442
428443 var runtime_slice = "hello";
429444 var runtime_i: usize = 3;
......@@ -456,6 +471,7 @@ test "inline for on tuple pointer" {
456471 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
457472 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
458473 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
474 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
459475
460476 const S = struct { u32, u32, u32 };
461477 var s: S = .{ 100, 200, 300 };
......@@ -471,6 +487,7 @@ test "ref counter that starts at zero" {
471487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
472488 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
473489 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
490 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
474491
475492 for ([_]usize{ 0, 1, 2 }, 0..) |i, j| {
476493 try expectEqual(i, j);
......@@ -486,6 +503,7 @@ test "inferred alloc ptr of for loop" {
486503 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
487504 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
488505 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
506 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
489507
490508 {
491509 var cond = false;
test/behavior/generics.zig+19
......@@ -19,6 +19,7 @@ fn checkSize(comptime T: type) usize {
1919test "simple generic fn" {
2020 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2121 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
22 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2223
2324 try expect(max(i32, 3, -1) == 3);
2425 try expect(max(u8, 1, 100) == 100);
......@@ -55,6 +56,7 @@ test "fn with comptime args" {
5556 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5657 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
5758 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5860
5961 try expect(gimmeTheBigOne(1234, 5678) == 5678);
6062 try expect(shouldCallSameInstance(34, 12) == 34);
......@@ -65,6 +67,7 @@ test "anytype params" {
6567 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6668 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
6769 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6871
6972 try expect(max_i32(12, 34) == 34);
7073 try expect(max_f64(1.2, 3.4) == 3.4);
......@@ -89,6 +92,7 @@ fn max_f64(a: f64, b: f64) f64 {
8992test "type constructed by comptime function call" {
9093 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
95 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9296
9397 var l: SimpleList(10) = undefined;
9498 l.array[0] = 10;
......@@ -113,6 +117,7 @@ test "function with return type type" {
113117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
114118 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
115119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
120 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
116121
117122 var list: List(i32) = undefined;
118123 var list2: List(i32) = undefined;
......@@ -154,6 +159,7 @@ test "generic fn with implicit cast" {
154159 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
155160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
156161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
157163
158164 try expect(getFirstByte(u8, &[_]u8{13}) == 13);
159165 try expect(getFirstByte(u16, &[_]u16{
......@@ -172,6 +178,7 @@ test "generic fn keeps non-generic parameter types" {
172178 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
173179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
174180 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
181 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
175182
176183 const A = 128;
177184
......@@ -280,6 +287,7 @@ test "generic function instantiation turns into comptime call" {
280287
281288test "generic function with void and comptime parameter" {
282289 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
290 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
283291
284292 const S = struct { x: i32 };
285293 const namespace = struct {
......@@ -296,6 +304,7 @@ test "generic function with void and comptime parameter" {
296304test "anonymous struct return type referencing comptime parameter" {
297305 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
298306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
299308
300309 const S = struct {
301310 pub fn extraData(comptime T: type, index: usize) struct { data: T, end: usize } {
......@@ -314,6 +323,7 @@ test "generic function instantiation non-duplicates" {
314323 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
315324 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
316325 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
326 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
317327 if (builtin.os.tag == .wasi) return error.SkipZigTest;
318328
319329 const S = struct {
......@@ -385,6 +395,7 @@ test "extern function used as generic parameter" {
385395
386396test "generic struct as parameter type" {
387397 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
388399
389400 const S = struct {
390401 fn doTheTest(comptime Int: type, thing: struct { int: Int }) !void {
......@@ -399,6 +410,8 @@ test "generic struct as parameter type" {
399410}
400411
401412test "slice as parameter type" {
413 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
414
402415 const S = struct {
403416 fn internComptimeString(comptime str: []const u8) *const []const u8 {
404417 return &struct {
......@@ -423,6 +436,7 @@ test "null sentinel pointer passed as generic argument" {
423436
424437test "generic function passed as comptime argument" {
425438 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
439 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
426440
427441 const S = struct {
428442 fn doMath(comptime f: fn (type, i32, i32) error{Overflow}!i32, a: i32, b: i32) !void {
......@@ -435,6 +449,7 @@ test "generic function passed as comptime argument" {
435449
436450test "return type of generic function is function pointer" {
437451 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
452 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
438453
439454 const S = struct {
440455 fn b(comptime T: type) ?*const fn () error{}!T {
......@@ -447,6 +462,7 @@ test "return type of generic function is function pointer" {
447462
448463test "coerced function body has inequal value with its uncoerced body" {
449464 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
465 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
450466
451467 const S = struct {
452468 const A = B(i32, c);
......@@ -496,6 +512,7 @@ test "union in struct captures argument" {
496512test "function argument tuple used as struct field" {
497513 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
498514 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
515 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
499516
500517 const S = struct {
501518 fn DeleagateWithContext(comptime Function: type) type {
......@@ -530,6 +547,7 @@ test "call generic function with from function called by the generic function" {
530547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
531548 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
532549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
550 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
533551 if (builtin.zig_backend == .stage2_llvm and
534552 builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) return error.SkipZigTest;
535553
......@@ -572,6 +590,7 @@ fn StructCapture(comptime T: type) type {
572590
573591test "call generic function that uses capture from function declaration's scope" {
574592 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
593 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
575594
576595 const S = StructCapture(f64);
577596 const s = S.foo(123);
test/behavior/globals.zig+3
......@@ -7,6 +7,7 @@ test "store to global array" {
77 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011
1112 try expect(pos[1] == 0.0);
1213 pos = [2]f32{ 0.0, 1.0 };
......@@ -18,6 +19,7 @@ test "store to global vector" {
1819 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1920 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2021 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
22 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2123
2224 try expect(vpos[1] == 0.0);
2325 vpos = @Vector(2, f32){ 0.0, 1.0 };
......@@ -28,6 +30,7 @@ test "slices pointing at the same address as global array." {
2830 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2931 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3032 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3134
3235 const S = struct {
3336 const a = [_]u8{ 1, 2, 3 };
test/behavior/hasdecl.zig+4
......@@ -12,6 +12,8 @@ const Bar = struct {
1212};
1313
1414test "@hasDecl" {
15 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16
1517 try expect(@hasDecl(Foo, "public_thing"));
1618 try expect(!@hasDecl(Foo, "private_thing"));
1719 try expect(!@hasDecl(Foo, "no_thing"));
......@@ -22,6 +24,8 @@ test "@hasDecl" {
2224}
2325
2426test "@hasDecl using a sliced string literal" {
27 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
28
2529 try expect(@hasDecl(@This(), "std") == true);
2630 try expect(@hasDecl(@This(), "std"[0..0]) == false);
2731 try expect(@hasDecl(@This(), "std"[0..1]) == false);
test/behavior/if.zig+8
......@@ -45,6 +45,7 @@ var global_with_err: anyerror!u32 = error.SomeError;
4545
4646test "unwrap mutable global var" {
4747 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4849
4950 if (global_with_val) |v| {
5051 try expect(v == 0);
......@@ -82,6 +83,7 @@ test "const result loc, runtime if cond, else unreachable" {
8283test "if copies its payload" {
8384 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8485 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
86 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8587
8688 const S = struct {
8789 fn doTheTest() !void {
......@@ -118,6 +120,7 @@ test "if peer expressions inferred optional type" {
118120 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
119121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
120122 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
121124
122125 var self: []const u8 = "abcdef";
123126 var index: usize = 0;
......@@ -136,6 +139,7 @@ test "if-else expression with runtime condition result location is inferred opti
136139 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
137140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
138141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
139143
140144 const A = struct { b: u64, c: u64 };
141145 var d: bool = true;
......@@ -145,6 +149,8 @@ test "if-else expression with runtime condition result location is inferred opti
145149}
146150
147151test "result location with inferred type ends up being pointer to comptime_int" {
152 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
153
148154 var a: ?u32 = 1234;
149155 var b: u32 = 2000;
150156 _ = .{ &a, &b };
......@@ -190,6 +196,8 @@ test "if value shouldn't be load-elided if used later (structs)" {
190196}
191197
192198test "if value shouldn't be load-elided if used later (optionals)" {
199 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
200
193201 var a: ?i32 = 1;
194202 var b: ?i32 = 1;
195203
test/behavior/import.zig+4
......@@ -6,18 +6,21 @@ const a_namespace = @import("import/a_namespace.zig");
66
77test "call fn via namespace lookup" {
88 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910
1011 try expect(@as(i32, 1234) == a_namespace.foo());
1112}
1213
1314test "importing the same thing gives the same import" {
1415 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1517
1618 try expect(@import("std") == @import("std"));
1719}
1820
1921test "import in non-toplevel scope" {
2022 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2124
2225 const S = struct {
2326 usingnamespace @import("import/a_namespace.zig");
......@@ -27,6 +30,7 @@ test "import in non-toplevel scope" {
2730
2831test "import empty file" {
2932 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
33 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3034
3135 _ = @import("import/empty.zig");
3236}
test/behavior/import_c_keywords.zig+1
......@@ -33,6 +33,7 @@ test "import c keywords" {
3333 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
3434 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
3535 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff) return error.SkipZigTest;
36 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3637
3738 try std.testing.expect(int == .c_keyword_variable);
3839 try std.testing.expect(long == .c_keyword_variable);
test/behavior/incomplete_struct_param_tld.zig+1
......@@ -23,6 +23,7 @@ fn foo(a: A) i32 {
2323
2424test "incomplete struct param top level declaration" {
2525 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2627
2728 const a = A{
2829 .b = B{
test/behavior/inline_switch.zig+9
......@@ -5,6 +5,7 @@ const builtin = @import("builtin");
55test "inline scalar prongs" {
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
89
910 var x: usize = 0;
1011 switch (x) {
......@@ -20,6 +21,7 @@ test "inline scalar prongs" {
2021test "inline prong ranges" {
2122 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2223 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2325
2426 var x: usize = 0;
2527 _ = &x;
......@@ -35,6 +37,7 @@ const E = enum { a, b, c, d };
3537test "inline switch enums" {
3638 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3739 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
40 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3841
3942 var x: E = .a;
4043 _ = &x;
......@@ -49,6 +52,7 @@ test "inline switch unions" {
4952 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5053 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5154 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
55 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5256
5357 var x: U = .a;
5458 _ = &x;
......@@ -75,6 +79,7 @@ test "inline switch unions" {
7579test "inline else bool" {
7680 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7781 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
82 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7883
7984 var a = true;
8085 _ = &a;
......@@ -87,6 +92,7 @@ test "inline else bool" {
8792test "inline else error" {
8893 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8994 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
95 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9096
9197 const Err = error{ a, b, c };
9298 var a = Err.a;
......@@ -100,6 +106,7 @@ test "inline else error" {
100106test "inline else enum" {
101107 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
102108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
103110
104111 const E2 = enum(u8) { a = 2, b = 3, c = 4, d = 5 };
105112 var a: E2 = .a;
......@@ -113,6 +120,7 @@ test "inline else enum" {
113120test "inline else int with gaps" {
114121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
115122 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
116124
117125 var a: u8 = 0;
118126 _ = &a;
......@@ -131,6 +139,7 @@ test "inline else int with gaps" {
131139test "inline else int all values" {
132140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
133141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
134143
135144 var a: u2 = 0;
136145 _ = &a;
test/behavior/int128.zig+5
......@@ -9,6 +9,7 @@ test "uint128" {
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1213
1314 var buff: u128 = maxInt(u128);
1415 try expect(buff == maxInt(u128));
......@@ -28,6 +29,7 @@ test "undefined 128 bit int" {
2829 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2930 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3031 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
32 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3133
3234 @setRuntimeSafety(true);
3335
......@@ -47,6 +49,7 @@ test "int128" {
4749 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4850 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4951 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5053
5154 var buff: i128 = -1;
5255 try expect(buff < 0 and (buff + 1) == 0);
......@@ -70,6 +73,7 @@ test "truncate int128" {
7073 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7174 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7275 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7377
7478 {
7579 var buff: u128 = maxInt(u128);
......@@ -93,6 +97,7 @@ test "shift int128" {
9397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9498 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9599 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
100 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
96101
97102 const types = .{ u128, i128 };
98103 inline for (types) |t| {
test/behavior/int_comparison_elision.zig+2
......@@ -4,6 +4,8 @@ const maxInt = std.math.maxInt;
44const builtin = @import("builtin");
55
66test "int comparison elision" {
7 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8
79 testIntEdges(u0);
810 testIntEdges(i0);
911 testIntEdges(u1);
test/behavior/int_div.zig+2
......@@ -6,6 +6,7 @@ test "integer division" {
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
77 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
88 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910
1011 try testDivision();
1112 try comptime testDivision();
......@@ -97,6 +98,7 @@ test "large integer division" {
9798 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
9899 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
99100 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
101 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
100102
101103 {
102104 var numerator: u256 = 99999999999999999997315645440;
test/behavior/ir_block_deps.zig+1
......@@ -21,6 +21,7 @@ test "ir block deps" {
2121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2323 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2425
2526 try expect((foo(1) catch unreachable) == 0);
2627 try expect((foo(2) catch unreachable) == 0);
test/behavior/lower_strlit_to_vector.zig+1
......@@ -6,6 +6,7 @@ test "strlit to vector" {
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910
1011 const strlit = "0123456789abcdef0123456789ABCDEF";
1112 const vec_from_strlit: @Vector(32, u8) = strlit.*;
test/behavior/math.zig+61
......@@ -12,6 +12,7 @@ const math = std.math;
1212test "assignment operators" {
1313 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1414 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1516
1617 var i: u32 = 0;
1718 i += 5;
......@@ -64,6 +65,7 @@ test "@clz" {
6465 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6566 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6667 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6769
6870 try testClz();
6971 try comptime testClz();
......@@ -82,6 +84,7 @@ test "@clz big ints" {
8284 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8385 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8486 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
87 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8588
8689 try testClzBigInts();
8790 try comptime testClzBigInts();
......@@ -103,6 +106,7 @@ test "@clz vectors" {
103106 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
104107 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
105108 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
106110
107111 try testClzVectors();
108112 try comptime testClzVectors();
......@@ -146,6 +150,7 @@ test "@ctz" {
146150 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
147151 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
148152 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
153 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
149154
150155 try testCtz();
151156 try comptime testCtz();
......@@ -169,6 +174,7 @@ test "@ctz 128-bit integers" {
169174 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
170175 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
171176 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
177 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
172178
173179 try testCtz128();
174180 try comptime testCtz128();
......@@ -187,6 +193,7 @@ test "@ctz vectors" {
187193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
188194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
189195 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
196 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
190197
191198 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
192199 // This regressed with LLVM 14:
......@@ -229,6 +236,7 @@ test "float equality" {
229236 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
230237 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
231238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
232240
233241 const x: f64 = 0.012;
234242 const y: f64 = x + 1.0;
......@@ -343,6 +351,8 @@ test "comptime_int multi-limb partial shift right" {
343351}
344352
345353test "xor" {
354 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
355
346356 try test_xor();
347357 try comptime test_xor();
348358}
......@@ -385,6 +395,8 @@ fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int
385395}
386396
387397test "binary not" {
398 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
399
388400 try expect(comptime x: {
389401 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
390402 });
......@@ -407,6 +419,7 @@ test "binary not 128-bit" {
407419 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
408420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
409421 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
422 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
410423
411424 try expect(comptime x: {
412425 break :x ~@as(u128, 0x55555555_55555555_55555555_55555555) == 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaaa;
......@@ -430,6 +443,7 @@ test "division" {
430443 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
431444 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
432445 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
446 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
433447
434448 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
435449 // https://github.com/ziglang/zig/issues/16846
......@@ -518,6 +532,7 @@ test "division half-precision floats" {
518532 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
519533 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
520534 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
535 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
521536
522537 try testDivisionFP16();
523538 try comptime testDivisionFP16();
......@@ -554,6 +569,8 @@ fn mod(comptime T: type, a: T, b: T) T {
554569}
555570
556571test "unsigned wrapping" {
572 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
573
557574 try testUnsignedWrappingEval(maxInt(u32));
558575 try comptime testUnsignedWrappingEval(maxInt(u32));
559576}
......@@ -565,6 +582,8 @@ fn testUnsignedWrappingEval(x: u32) !void {
565582}
566583
567584test "signed wrapping" {
585 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
586
568587 try testSignedWrappingEval(maxInt(i32));
569588 try comptime testSignedWrappingEval(maxInt(i32));
570589}
......@@ -576,6 +595,8 @@ fn testSignedWrappingEval(x: i32) !void {
576595}
577596
578597test "signed negation wrapping" {
598 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
599
579600 try testSignedNegationWrappingEval(minInt(i16));
580601 try comptime testSignedNegationWrappingEval(minInt(i16));
581602}
......@@ -586,6 +607,8 @@ fn testSignedNegationWrappingEval(x: i16) !void {
586607}
587608
588609test "unsigned negation wrapping" {
610 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
611
589612 try testUnsignedNegationWrappingEval(1);
590613 try comptime testUnsignedNegationWrappingEval(1);
591614}
......@@ -598,6 +621,7 @@ fn testUnsignedNegationWrappingEval(x: u16) !void {
598621test "negation wrapping" {
599622 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
600623 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
624 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
601625
602626 try expectEqual(@as(u1, 1), negateWrap(u1, 1));
603627}
......@@ -611,6 +635,7 @@ fn negateWrap(comptime T: type, x: T) T {
611635test "unsigned 64-bit division" {
612636 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
613637 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
638 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
614639
615640 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
616641 // https://github.com/ziglang/zig/issues/16846
......@@ -644,6 +669,8 @@ test "bit shift a u1" {
644669}
645670
646671test "truncating shift right" {
672 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
673
647674 try testShrTrunc(maxInt(u16));
648675 try comptime testShrTrunc(maxInt(u16));
649676}
......@@ -658,6 +685,7 @@ test "f128" {
658685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
659686 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
660687 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
688 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
661689
662690 try test_f128();
663691 try comptime test_f128();
......@@ -689,6 +717,7 @@ test "128-bit multiplication" {
689717 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
690718 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
691719 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
720 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
692721
693722 {
694723 var a: i128 = 3;
......@@ -715,6 +744,7 @@ test "@addWithOverflow" {
715744 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
716745 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
717746 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
747 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
718748
719749 {
720750 var a: u8 = 250;
......@@ -765,6 +795,7 @@ test "@addWithOverflow" {
765795test "small int addition" {
766796 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
767797 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
798 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
768799
769800 var x: u2 = 0;
770801 try expect(x == 0);
......@@ -786,6 +817,7 @@ test "small int addition" {
786817test "basic @mulWithOverflow" {
787818 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
788819 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
820 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
789821
790822 {
791823 var a: u8 = 86;
......@@ -818,6 +850,7 @@ test "basic @mulWithOverflow" {
818850test "extensive @mulWithOverflow" {
819851 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
820852 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
853 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
821854
822855 {
823856 var a: u5 = 3;
......@@ -989,6 +1022,8 @@ test "extensive @mulWithOverflow" {
9891022}
9901023
9911024test "@mulWithOverflow bitsize > 32" {
1025 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1026
9921027 // aarch64 fails on a release build of the compiler.
9931028 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9941029 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
......@@ -1056,6 +1091,7 @@ test "@mulWithOverflow u256" {
10561091 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
10571092 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
10581093 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1094 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10591095
10601096 {
10611097 const const_lhs: u256 = 8035709466408580321693645878924206181189;
......@@ -1091,6 +1127,7 @@ test "@subWithOverflow" {
10911127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10921128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10931129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1130 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10941131
10951132 {
10961133 var a: u8 = 1;
......@@ -1143,6 +1180,7 @@ test "@shlWithOverflow" {
11431180 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11441181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11451182 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1183 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11461184
11471185 {
11481186 var a: u4 = 2;
......@@ -1250,6 +1288,7 @@ test "quad hex float literal parsing accurate" {
12501288 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12511289 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12521290 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1291 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12531292
12541293 const a: f128 = 0x1.1111222233334444555566667777p+0;
12551294
......@@ -1345,6 +1384,8 @@ test "quad hex float literal parsing accurate" {
13451384}
13461385
13471386test "truncating shift left" {
1387 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1388
13481389 try testShlTrunc(maxInt(u16));
13491390 try comptime testShlTrunc(maxInt(u16));
13501391}
......@@ -1354,6 +1395,8 @@ fn testShlTrunc(x: u16) !void {
13541395}
13551396
13561397test "exact shift left" {
1398 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1399
13571400 try testShlExact(0b00110101);
13581401 try comptime testShlExact(0b00110101);
13591402
......@@ -1365,6 +1408,8 @@ fn testShlExact(x: u8) !void {
13651408}
13661409
13671410test "exact shift right" {
1411 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1412
13681413 try testShrExact(0b10110100);
13691414 try comptime testShrExact(0b10110100);
13701415}
......@@ -1374,6 +1419,8 @@ fn testShrExact(x: u8) !void {
13741419}
13751420
13761421test "shift left/right on u0 operand" {
1422 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1423
13771424 const S = struct {
13781425 fn doTheTest() !void {
13791426 var x: u0 = 0;
......@@ -1408,6 +1455,7 @@ test "remainder division" {
14081455 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14091456 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
14101457 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1458 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14111459
14121460 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
14131461 // https://github.com/ziglang/zig/issues/12602
......@@ -1446,6 +1494,7 @@ test "float remainder division using @rem" {
14461494 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14471495 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14481496 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1497 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14491498
14501499 try comptime frem(f16);
14511500 try comptime frem(f32);
......@@ -1489,6 +1538,7 @@ test "float modulo division using @mod" {
14891538 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14901539 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14911540 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1541 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14921542
14931543 try comptime fmod(f16);
14941544 try comptime fmod(f32);
......@@ -1531,6 +1581,7 @@ test "@round f16" {
15311581 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15321582 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15331583 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1584 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15341585
15351586 try testRound(f16, 12.0);
15361587 try comptime testRound(f16, 12.0);
......@@ -1542,6 +1593,7 @@ test "@round f32/f64" {
15421593 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15431594 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15441595 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1596 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15451597
15461598 try testRound(f64, 12.0);
15471599 try comptime testRound(f64, 12.0);
......@@ -1561,6 +1613,7 @@ test "@round f80" {
15611613 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15621614 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
15631615 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1616 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15641617
15651618 try testRound(f80, 12.0);
15661619 try comptime testRound(f80, 12.0);
......@@ -1573,6 +1626,7 @@ test "@round f128" {
15731626 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
15741627 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
15751628 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1629 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15761630
15771631 try testRound(f128, 12.0);
15781632 try comptime testRound(f128, 12.0);
......@@ -1590,6 +1644,7 @@ test "vector integer addition" {
15901644 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15911645 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
15921646 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1647 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15931648
15941649 const S = struct {
15951650 fn doTheTest() !void {
......@@ -1612,6 +1667,7 @@ test "NaN comparison" {
16121667 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16131668 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
16141669 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1670 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16151671
16161672 try testNanEqNan(f16);
16171673 try testNanEqNan(f32);
......@@ -1629,6 +1685,7 @@ test "NaN comparison f80" {
16291685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16301686 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
16311687 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1688 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16321689
16331690 try testNanEqNan(f80);
16341691 try comptime testNanEqNan(f80);
......@@ -1651,6 +1708,7 @@ test "vector comparison" {
16511708 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16521709 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16531710 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1711 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16541712 if (builtin.zig_backend == .stage2_x86_64 and
16551713 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return error.SkipZigTest;
16561714
......@@ -1683,6 +1741,7 @@ test "signed zeros are represented properly" {
16831741 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16841742 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16851743 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1744 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16861745
16871746 const S = struct {
16881747 fn doTheTest() !void {
......@@ -1712,6 +1771,7 @@ test "absFloat" {
17121771 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17131772 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17141773 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1774 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17151775
17161776 try testAbsFloat();
17171777 try comptime testAbsFloat();
......@@ -1745,6 +1805,7 @@ test "@clz works on both vector and scalar inputs" {
17451805 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17461806 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17471807 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1808 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17481809
17491810 var x: u32 = 0x1;
17501811 _ = &x;
test/behavior/maximum_minimum.zig+10
......@@ -9,6 +9,7 @@ test "@max" {
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1213
1314 const S = struct {
1415 fn doTheTest() !void {
......@@ -31,6 +32,7 @@ test "@max on vectors" {
3132 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
3233 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3334 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
35 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3436 if (builtin.zig_backend == .stage2_x86_64 and
3537 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
3638
......@@ -63,6 +65,7 @@ test "@min" {
6365 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6567 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6669
6770 const S = struct {
6871 fn doTheTest() !void {
......@@ -85,6 +88,7 @@ test "@min for vectors" {
8588 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8689 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8790 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
91 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8892 if (builtin.zig_backend == .stage2_x86_64 and
8993 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
9094
......@@ -120,6 +124,7 @@ test "@min/max for floats" {
120124 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
121125 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
122126 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
123128
124129 const S = struct {
125130 fn doTheTest(comptime T: type) !void {
......@@ -167,6 +172,7 @@ test "@min/@max more than two vector arguments" {
167172 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
168173 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
169174 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
175 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
170176
171177 const x: @Vector(2, u32) = .{ 3, 2 };
172178 const y: @Vector(2, u32) = .{ 4, 1 };
......@@ -198,6 +204,7 @@ test "@min/@max notices vector bounds" {
198204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
199205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
200206 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
207 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
201208
202209 var x: @Vector(2, u16) = .{ 140, 40 };
203210 const y: @Vector(2, u64) = .{ 5, 100 };
......@@ -251,6 +258,7 @@ test "@min/@max notices bounds from vector types" {
251258 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
252259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
253260 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
261 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
254262
255263 var x: @Vector(2, u16) = .{ 30, 67 };
256264 var y: @Vector(2, u32) = .{ 20, 500 };
......@@ -271,6 +279,7 @@ test "@min/@max notices bounds from types when comptime-known value is undef" {
271279 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
272280 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
273281 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
282 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
274283
275284 var x: u32 = 1_000_000;
276285 _ = &x;
......@@ -291,6 +300,7 @@ test "@min/@max notices bounds from vector types when element of comptime-known
291300 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
292301 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
293302 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
303 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
294304 if (builtin.zig_backend == .stage2_x86_64 and
295305 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx)) return error.SkipZigTest;
296306
test/behavior/member_func.zig+2
......@@ -31,6 +31,7 @@ test "standard field calls" {
3131 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3333 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
34 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3435
3536 try expect(HasFuncs.one(0) == 1);
3637 try expect(HasFuncs.two(0) == 2);
......@@ -75,6 +76,7 @@ test "@field field calls" {
7576 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7677 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7778 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
79 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7880
7981 try expect(@field(HasFuncs, "one")(0) == 1);
8082 try expect(@field(HasFuncs, "two")(0) == 2);
test/behavior/memcpy.zig+4
......@@ -7,6 +7,7 @@ test "memcpy and memset intrinsics" {
77 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
88 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011
1112 try testMemcpyMemset();
1213 try comptime testMemcpyMemset();
......@@ -28,6 +29,7 @@ test "@memcpy with both operands single-ptr-to-array, one is null-terminated" {
2829 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2930 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3031 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
32 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3133
3234 try testMemcpyBothSinglePtrArrayOneIsNullTerminated();
3335 try comptime testMemcpyBothSinglePtrArrayOneIsNullTerminated();
......@@ -48,6 +50,7 @@ test "@memcpy dest many pointer" {
4850 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
4951 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5052 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
53 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5154
5255 try testMemcpyDestManyPtr();
5356 try comptime testMemcpyDestManyPtr();
......@@ -70,6 +73,7 @@ test "@memcpy slice" {
7073 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7174 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7275 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7377
7478 try testMemcpySlice();
7579 try comptime testMemcpySlice();
test/behavior/memset.zig+9
......@@ -7,6 +7,7 @@ test "@memset on array pointers" {
77 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
88 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011
1112 try testMemsetArray();
1213 try comptime testMemsetArray();
......@@ -36,6 +37,7 @@ test "@memset on slices" {
3637 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3738 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
3839 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
40 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3941
4042 try testMemsetSlice();
4143 try comptime testMemsetSlice();
......@@ -71,6 +73,7 @@ test "memset with bool element" {
7173 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7274 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
7375 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7477
7578 var buf: [5]bool = undefined;
7679 @memset(&buf, true);
......@@ -83,6 +86,7 @@ test "memset with 1-byte struct element" {
8386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
8588 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
89 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8690
8791 const S = struct { x: bool };
8892 var buf: [5]S = undefined;
......@@ -96,6 +100,7 @@ test "memset with 1-byte array element" {
96100 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
97101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
98102 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
103 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
99104
100105 const A = [1]bool;
101106 var buf: [5]A = undefined;
......@@ -109,6 +114,7 @@ test "memset with large array element, runtime known" {
109114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
110115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
111116 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
117 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
112118
113119 const A = [128]u64;
114120 var buf: [5]A = undefined;
......@@ -127,6 +133,7 @@ test "memset with large array element, comptime known" {
127133 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
128134 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
129135 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
136 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
130137
131138 const A = [128]u64;
132139 var buf: [5]A = undefined;
......@@ -144,6 +151,7 @@ test "@memset provides result type" {
144151 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
145152 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
146153 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
154 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
147155
148156 const S = struct { x: u32 };
149157
......@@ -162,6 +170,7 @@ test "zero keys with @memset" {
162170 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
163171 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
164172 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
173 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
165174
166175 const Keys = struct {
167176 up: bool,
test/behavior/merge_error_sets.zig+1
......@@ -13,6 +13,7 @@ fn foo() C!void {
1313
1414test "merge error sets" {
1515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1617
1718 if (foo()) {
1819 @panic("unexpected");
test/behavior/muladd.zig+10
......@@ -6,6 +6,8 @@ const no_x86_64_hardware_fma_support = builtin.zig_backend == .stage2_x86_64 and
66 !std.Target.x86.featureSetHas(builtin.cpu.features, .fma);
77
88test "@mulAdd" {
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10
911 if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
1012 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
......@@ -37,6 +39,7 @@ test "@mulAdd f16" {
3739 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3840 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3941 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
42 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4043
4144 try comptime testMulAdd16();
4245 try testMulAdd16();
......@@ -57,6 +60,7 @@ test "@mulAdd f80" {
5760 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5861 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
5962 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
63 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6064
6165 try comptime testMulAdd80();
6266 try testMulAdd80();
......@@ -77,6 +81,7 @@ test "@mulAdd f128" {
7781 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7882 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
7983 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
84 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8085
8186 try comptime testMulAdd128();
8287 try testMulAdd128();
......@@ -109,6 +114,7 @@ test "vector f16" {
109114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
110115 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
111116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
117 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
112118
113119 try comptime vector16();
114120 try vector16();
......@@ -129,6 +135,7 @@ fn vector32() !void {
129135
130136test "vector f32" {
131137 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
132139 if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
133140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
134141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
......@@ -153,6 +160,7 @@ fn vector64() !void {
153160
154161test "vector f64" {
155162 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
156164 if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
157165 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
158166 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
......@@ -182,6 +190,7 @@ test "vector f80" {
182190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
183191 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
184192 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
193 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185194
186195 try comptime vector80();
187196 try vector80();
......@@ -208,6 +217,7 @@ test "vector f128" {
208217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
209218 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
210219 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
220 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
211221
212222 try comptime vector128();
213223 try vector128();
test/behavior/multiple_externs_with_conflicting_types.zig+1
......@@ -16,6 +16,7 @@ test "call extern function defined with conflicting type" {
1616 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1717 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1818 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1920
2021 @import("conflicting_externs/a.zig").issue529(null);
2122 issue529(null);
test/behavior/namespace_depends_on_compile_var.zig+1
......@@ -4,6 +4,7 @@ const expect = std.testing.expect;
44
55test "namespace depends on compile var" {
66 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
78
89 if (some_namespace.a_bool) {
910 try expect(some_namespace.a_bool);
test/behavior/nan.zig+1
......@@ -26,6 +26,7 @@ test "nan memory equality" {
2626 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2727 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2828 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
29 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2930
3031 // signaled
3132 try testing.expect(mem.eql(u8, mem.asBytes(&snan_u16), mem.asBytes(&snan_f16)));
test/behavior/null.zig+8
......@@ -32,6 +32,7 @@ test "test maybe object and get a pointer to the inner value" {
3232 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3333 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
35 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3536
3637 var maybe_bool: ?bool = true;
3738
......@@ -52,6 +53,7 @@ test "maybe return" {
5253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5354 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
5455 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5557
5658 try maybeReturnImpl();
5759 try comptime maybeReturnImpl();
......@@ -71,6 +73,7 @@ fn foo(x: ?i32) ?bool {
7173test "test null runtime" {
7274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7375 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7477
7578 try testTestNullRuntime(null);
7679}
......@@ -82,6 +85,7 @@ fn testTestNullRuntime(x: ?i32) !void {
8285test "optional void" {
8386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8487 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8589
8690 try optionalVoidImpl();
8791 try comptime optionalVoidImpl();
......@@ -105,6 +109,7 @@ const Empty = struct {};
105109test "optional struct{}" {
106110 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
107111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
108113
109114 _ = try optionalEmptyStructImpl();
110115 _ = try comptime optionalEmptyStructImpl();
......@@ -130,6 +135,7 @@ test "null with default unwrap" {
130135
131136test "optional pointer to 0 bit type null value at runtime" {
132137 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
133139
134140 const EmptyStruct = struct {};
135141 var x: ?*EmptyStruct = null;
......@@ -141,6 +147,7 @@ test "if var maybe pointer" {
141147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
142148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
143149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
150 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
144151
145152 try expect(shouldBeAPlus1(Particle{
146153 .a = 14,
......@@ -184,6 +191,7 @@ test "unwrap optional which is field of global var" {
184191 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
185192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
186193 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
187195
188196 struct_with_optional.field = null;
189197 if (struct_with_optional.field) |payload| {
test/behavior/optional.zig+27
......@@ -9,6 +9,7 @@ const expectEqualStrings = std.testing.expectEqualStrings;
99test "passing an optional integer as a parameter" {
1010 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1213
1314 const S = struct {
1415 fn entry() bool {
......@@ -28,6 +29,7 @@ pub const EmptyStruct = struct {};
2829
2930test "optional pointer to size zero struct" {
3031 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3133
3234 var e = EmptyStruct{};
3335 const o: ?*EmptyStruct = &e;
......@@ -58,6 +60,7 @@ fn testNullPtrsEql() !void {
5860test "optional with zero-bit type" {
5961 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
6062 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
63 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6164
6265 const S = struct {
6366 fn doTheTest(comptime ZeroBit: type, comptime zero_bit: ZeroBit) !void {
......@@ -110,6 +113,7 @@ test "address of unwrap optional" {
110113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
111114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
112115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
116 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
113117
114118 const S = struct {
115119 const Foo = struct {
......@@ -131,6 +135,7 @@ test "nested optional field in struct" {
131135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
132136 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
133137 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
134139
135140 const S2 = struct {
136141 y: u8,
......@@ -149,6 +154,7 @@ test "equality compare optionals and non-optionals" {
149154 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
150155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
151156 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
157 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
152158
153159 const S = struct {
154160 fn doTheTest() !void {
......@@ -206,6 +212,7 @@ test "equality compare optionals and non-optionals" {
206212
207213test "compare optionals with modified payloads" {
208214 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
215 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
209216
210217 var lhs: ?bool = false;
211218 const lhs_payload = &lhs.?;
......@@ -233,6 +240,7 @@ test "compare optionals with modified payloads" {
233240test "unwrap function call with optional pointer return value" {
234241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
235242 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
243 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
236244
237245 const S = struct {
238246 fn entry() !void {
......@@ -254,6 +262,7 @@ test "unwrap function call with optional pointer return value" {
254262test "nested orelse" {
255263 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256264 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
265 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
257266
258267 const S = struct {
259268 fn entry() !void {
......@@ -280,6 +289,7 @@ test "nested orelse" {
280289test "self-referential struct through a slice of optional" {
281290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
282291 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
292 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
283293
284294 const S = struct {
285295 const Node = struct {
......@@ -316,6 +326,7 @@ test "coerce an anon struct literal to optional struct" {
316326 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
317327 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
318328 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
329 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
319330
320331 const S = struct {
321332 const Struct = struct {
......@@ -335,6 +346,7 @@ test "0-bit child type coerced to optional return ptr result location" {
335346 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
336347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
337348 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
349 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
338350
339351 const S = struct {
340352 fn doTheTest() !void {
......@@ -360,6 +372,7 @@ test "0-bit child type coerced to optional return ptr result location" {
360372test "0-bit child type coerced to optional" {
361373 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
362374 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
375 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
363376
364377 const S = struct {
365378 fn doTheTest() !void {
......@@ -387,6 +400,7 @@ test "array of optional unaligned types" {
387400 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
388401 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
389402 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
403 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
390404
391405 const Enum = enum { one, two, three };
392406
......@@ -423,6 +437,7 @@ test "optional pointer to zero bit optional payload" {
423437 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
424438 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
425439 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
440 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
426441
427442 const B = struct {
428443 fn foo(_: *@This()) void {}
......@@ -442,6 +457,7 @@ test "optional pointer to zero bit error union payload" {
442457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
443458 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
444459 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
460 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
445461
446462 const B = struct {
447463 fn foo(_: *@This()) void {}
......@@ -475,6 +491,7 @@ const NoReturn = struct {
475491
476492test "optional of noreturn used with if" {
477493 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
494 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
478495
479496 NoReturn.a = 64;
480497 if (NoReturn.loop()) |_| {
......@@ -486,6 +503,7 @@ test "optional of noreturn used with if" {
486503
487504test "optional of noreturn used with orelse" {
488505 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
506 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
489507
490508 NoReturn.a = 64;
491509 const val = NoReturn.testOrelse();
......@@ -505,6 +523,7 @@ test "alignment of wrapping an optional payload" {
505523 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
506524 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
507525 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
526 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
508527
509528 const S = struct {
510529 const I = extern struct { x: i128 };
......@@ -522,6 +541,7 @@ test "Optional slice size is optimized" {
522541 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
523542 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
524543 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
544 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
525545
526546 try expect(@sizeOf(?[]u8) == @sizeOf([]u8));
527547 var a: ?[]const u8 = null;
......@@ -535,6 +555,7 @@ test "Optional slice passed to function" {
535555 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
536556 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
537557 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
558 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
538559
539560 const S = struct {
540561 fn foo(a: ?[]const u8) !void {
......@@ -551,6 +572,7 @@ test "Optional slice passed to function" {
551572test "peer type resolution in nested if expressions" {
552573 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
553574 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
575 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
554576
555577 const Thing = struct { n: i32 };
556578 var a = false;
......@@ -578,6 +600,7 @@ test "cast slice to const slice nested in error union and optional" {
578600 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
579601 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
580602 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
603 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
581604
582605 const S = struct {
583606 fn inner() !?[]u8 {
......@@ -591,6 +614,8 @@ test "cast slice to const slice nested in error union and optional" {
591614}
592615
593616test "variable of optional of noreturn" {
617 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
618
594619 var null_opv: ?noreturn = null;
595620 _ = &null_opv;
596621 try std.testing.expectEqual(@as(?noreturn, null), null_opv);
......@@ -600,6 +625,7 @@ test "copied optional doesn't alias source" {
600625 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
601626 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
602627 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
628 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
603629
604630 var opt_x: ?[3]f32 = [_]f32{0.0} ** 3;
605631
......@@ -614,6 +640,7 @@ test "result location initialization of optional with OPV payload" {
614640 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
615641 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
616642 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
643 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
617644
618645 const S = struct {
619646 x: u0,
test/behavior/packed-struct.zig+30
......@@ -238,6 +238,7 @@ test "regular in irregular packed struct" {
238238 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
239239 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
240240 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
241 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
241242
242243 const Irregular = packed struct {
243244 bar: Regular = Regular{},
......@@ -258,6 +259,7 @@ test "nested packed struct unaligned" {
258259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
259260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
260261 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
262 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
261263 if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet
262264
263265 const S1 = packed struct {
......@@ -330,6 +332,7 @@ test "byte-aligned field pointer offsets" {
330332 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
331333 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
332334 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
335 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
333336
334337 const S = struct {
335338 const A = packed struct {
......@@ -432,6 +435,7 @@ test "nested packed struct field pointers" {
432435 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
433436 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
434437 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access
438 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
435439 if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet
436440
437441 const S2 = packed struct {
......@@ -469,6 +473,7 @@ test "load pointer from packed struct" {
469473 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
470474 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
471475 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
476 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
472477
473478 const A = struct {
474479 index: u16,
......@@ -489,6 +494,7 @@ test "@intFromPtr on a packed struct field" {
489494 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
490495 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
491496 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
497 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
492498 if (native_endian != .little) return error.SkipZigTest;
493499
494500 const S = struct {
......@@ -512,6 +518,7 @@ test "@intFromPtr on a packed struct field unaligned and nested" {
512518 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
513519 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
514520 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
521 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
515522 if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet
516523
517524 const S1 = packed struct {
......@@ -618,6 +625,8 @@ test "@intFromPtr on a packed struct field unaligned and nested" {
618625}
619626
620627test "packed struct fields modification" {
628 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
629
621630 // Originally reported at https://github.com/ziglang/zig/issues/16615
622631 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
623632
......@@ -646,6 +655,7 @@ test "optional pointer in packed struct" {
646655 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
647656 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
648657 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
658 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
649659
650660 const T = packed struct { ptr: ?*const u8 };
651661 var n: u8 = 0;
......@@ -661,6 +671,7 @@ test "nested packed struct field access test" {
661671 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
662672 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
663673 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
674 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
664675
665676 const Vec2 = packed struct {
666677 x: f32,
......@@ -777,6 +788,7 @@ test "nested packed struct field access test" {
777788test "nested packed struct at non-zero offset" {
778789 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
779790 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
791 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
780792
781793 const Pair = packed struct(u24) {
782794 a: u16 = 0,
......@@ -810,6 +822,7 @@ test "nested packed struct at non-zero offset 2" {
810822 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
811823 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO packed structs larger than 64 bits
812824 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
825 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
813826
814827 const S = struct {
815828 const Pair = packed struct(u40) {
......@@ -890,6 +903,7 @@ test "packed struct passed to callconv(.C) function" {
890903 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
891904 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
892905 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
906 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
893907
894908 const S = struct {
895909 const Packed = packed struct {
......@@ -938,6 +952,7 @@ test "packed struct initialized in bitcast" {
938952 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
939953 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
940954 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
955 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
941956
942957 const T = packed struct { val: u8 };
943958 var val: u8 = 123;
......@@ -951,6 +966,7 @@ test "pointer to container level packed struct field" {
951966 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
952967 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
953968 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
969 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
954970
955971 const S = packed struct(u32) {
956972 test_bit: bool,
......@@ -975,6 +991,7 @@ test "store undefined to packed result location" {
975991 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
976992 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
977993 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
994 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
978995
979996 var x: u4 = 0;
980997 _ = &x;
......@@ -995,6 +1012,8 @@ test "bitcast back and forth" {
9951012}
9961013
9971014test "field access of packed struct smaller than its abi size inside struct initialized with rls" {
1015 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1016
9981017 // Originally reported at https://github.com/ziglang/zig/issues/14200
9991018 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10001019
......@@ -1013,6 +1032,8 @@ test "field access of packed struct smaller than its abi size inside struct init
10131032}
10141033
10151034test "modify nested packed struct aligned field" {
1035 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1036
10161037 // Originally reported at https://github.com/ziglang/zig/issues/14632
10171038 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10181039 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
......@@ -1043,6 +1064,8 @@ test "modify nested packed struct aligned field" {
10431064}
10441065
10451066test "assigning packed struct inside another packed struct" {
1067 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1068
10461069 // Originally reported at https://github.com/ziglang/zig/issues/9674
10471070 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10481071
......@@ -1077,6 +1100,7 @@ test "packed struct used as part of anon decl name" {
10771100 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10781101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10791102 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1103 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10801104
10811105 const S = packed struct { a: u0 = 0 };
10821106 var a: u8 = 0;
......@@ -1099,6 +1123,8 @@ test "packed struct acts as a namespace" {
10991123}
11001124
11011125test "pointer loaded correctly from packed struct" {
1126 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1127
11021128 const RAM = struct {
11031129 data: [0xFFFF + 1]u8,
11041130 fn new() !@This() {
......@@ -1142,6 +1168,7 @@ test "assignment to non-byte-aligned field in packed struct" {
11421168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11431169 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11441170 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1171 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11451172
11461173 const Frame = packed struct {
11471174 num: u20,
......@@ -1164,6 +1191,7 @@ test "packed struct field pointer aligned properly" {
11641191 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11651192 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11661193 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
1194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11671195
11681196 const Foo = packed struct {
11691197 a: i32,
......@@ -1183,6 +1211,7 @@ test "load flag from packed struct in union" {
11831211 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11841212 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11851213 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1214 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11861215
11871216 const A = packed struct {
11881217 a: bool,
......@@ -1251,6 +1280,7 @@ test "2-byte packed struct argument in C calling convention" {
12511280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
12521281 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
12531282 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1283 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12541284
12551285 const S = packed struct(u16) {
12561286 x: u15 = 0,
test/behavior/packed-union.zig+5
......@@ -8,6 +8,7 @@ test "flags in packed union" {
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1010 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1112
1213 try testFlagsInPackedUnion();
1314 try comptime testFlagsInPackedUnion();
......@@ -50,6 +51,7 @@ test "flags in packed union at offset" {
5051 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5152 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
5253 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
54 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5355
5456 try testFlagsInPackedUnionAtOffset();
5557 try comptime testFlagsInPackedUnionAtOffset();
......@@ -98,6 +100,8 @@ fn testFlagsInPackedUnionAtOffset() !void {
98100}
99101
100102test "packed union in packed struct" {
103 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
104
101105 // Originally reported at https://github.com/ziglang/zig/issues/16581
102106 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
103107
......@@ -137,6 +141,7 @@ test "packed union initialized with a runtime value" {
137141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
138142 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
139143 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
144 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
140145
141146 const Fields = packed struct {
142147 timestamp: u50,
test/behavior/pointers.zig+17
......@@ -20,6 +20,7 @@ fn testDerefPtr() !void {
2020test "pointer arithmetic" {
2121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2324
2425 var ptr: [*]const u8 = "abcd";
2526
......@@ -68,6 +69,7 @@ test "initialize const optional C pointer to null" {
6869
6970test "assigning integer to C pointer" {
7071 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7173
7274 var x: i32 = 0;
7375 var y: i32 = 1;
......@@ -85,6 +87,7 @@ test "assigning integer to C pointer" {
8587
8688test "C pointer comparison and arithmetic" {
8789 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
90 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8891
8992 const S = struct {
9093 fn doTheTest() !void {
......@@ -154,6 +157,7 @@ test "implicit casting between C pointer and optional non-C pointer" {
154157 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
155158 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
156159 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
160 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
157161
158162 var slice: []const u8 = "aoeu";
159163 _ = &slice;
......@@ -170,6 +174,7 @@ test "implicit cast error unions with non-optional to optional pointer" {
170174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
171175 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
172176 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
177 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
173178
174179 const S = struct {
175180 fn doTheTest() !void {
......@@ -197,6 +202,7 @@ test "allowzero pointer and slice" {
197202 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
198203 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
199204 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
205 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
200206
201207 var ptr: [*]allowzero i32 = @ptrFromInt(0);
202208 const opt_ptr: ?[*]allowzero i32 = ptr;
......@@ -216,6 +222,7 @@ test "assign null directly to C pointer and test null equality" {
216222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
217223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
218224 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
219226
220227 var x: [*c]i32 = null;
221228 _ = &x;
......@@ -283,6 +290,7 @@ test "array initialization types" {
283290test "null terminated pointer" {
284291 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
285292 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
293 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
286294
287295 const S = struct {
288296 fn doTheTest() !void {
......@@ -300,6 +308,7 @@ test "null terminated pointer" {
300308test "allow any sentinel" {
301309 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
302310 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
311 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
303312
304313 const S = struct {
305314 fn doTheTest() !void {
......@@ -315,6 +324,7 @@ test "allow any sentinel" {
315324test "pointer sentinel with enums" {
316325 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
317326 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
327 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
318328
319329 const S = struct {
320330 const Number = enum {
......@@ -337,6 +347,7 @@ test "pointer sentinel with optional element" {
337347 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
338348 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
339349 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
350 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
340351
341352 const S = struct {
342353 fn doTheTest() !void {
......@@ -353,6 +364,7 @@ test "pointer sentinel with +inf" {
353364 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
354365 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
355366 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
367 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
356368
357369 const S = struct {
358370 fn doTheTest() !void {
......@@ -430,6 +442,7 @@ test "indexing array with sentinel returns correct type" {
430442test "element pointer to slice" {
431443 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
432444 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
445 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
433446
434447 const S = struct {
435448 fn doTheTest() !void {
......@@ -452,6 +465,7 @@ test "element pointer to slice" {
452465test "element pointer arithmetic to slice" {
453466 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
454467 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
468 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
455469
456470 const S = struct {
457471 fn doTheTest() !void {
......@@ -476,6 +490,7 @@ test "element pointer arithmetic to slice" {
476490
477491test "array slicing to slice" {
478492 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
493 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
479494
480495 const S = struct {
481496 fn doTheTest() !void {
......@@ -506,6 +521,7 @@ test "ptrCast comptime known slice to C pointer" {
506521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
507522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
508523 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
524 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
509525
510526 const s: [:0]const u8 = "foo";
511527 var p: [*c]const u8 = @ptrCast(s);
......@@ -525,6 +541,7 @@ test "pointer alignment and element type include call expression" {
525541
526542test "pointer to array has explicit alignment" {
527543 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
544 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
528545
529546 const S = struct {
530547 const Base = extern struct { a: u8 };
test/behavior/popcount.zig+3
......@@ -8,6 +8,7 @@ test "@popCount integers" {
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1112
1213 try comptime testPopCountIntegers();
1314 try testPopCountIntegers();
......@@ -18,6 +19,7 @@ test "@popCount 128bit integer" {
1819 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1920 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2021 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
22 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2123
2224 comptime {
2325 try expect(@popCount(@as(u128, 0b11111111000110001100010000100001000011000011100101010001)) == 24);
......@@ -81,6 +83,7 @@ test "@popCount vectors" {
8183 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8284 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8385 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
86 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8487
8588 try comptime testPopCountVectors();
8689 try testPopCountVectors();
test/behavior/prefetch.zig+1
......@@ -3,6 +3,7 @@ const std = @import("std");
33
44test "@prefetch()" {
55 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
67
78 var a: [2]u32 = .{ 42, 42 };
89 var a_len = a.len;
test/behavior/ptrcast.zig+3
......@@ -58,6 +58,7 @@ fn testReinterpretStructWrappedBytesAsInteger() !void {
5858test "reinterpret bytes of an array into an extern struct" {
5959 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6060 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6162
6263 try testReinterpretBytesAsExternStruct();
6364 try comptime testReinterpretBytesAsExternStruct();
......@@ -232,6 +233,7 @@ test "implicit optional pointer to optional anyopaque pointer" {
232233 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
233234 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
234235 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
236 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
235237
236238 var buf: [4]u8 = "aoeu".*;
237239 const x: ?[*]u8 = &buf;
......@@ -244,6 +246,7 @@ test "@ptrCast slice to slice" {
244246 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
245247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
246248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
249 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
247250
248251 const S = struct {
249252 fn foo(slice: []u32) []i32 {
test/behavior/ptrfromint.zig+5
......@@ -3,6 +3,8 @@ const builtin = @import("builtin");
33const expectEqual = std.testing.expectEqual;
44
55test "casting integer address to function pointer" {
6 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7
68 addressToFunction();
79 comptime addressToFunction();
810}
......@@ -17,6 +19,7 @@ test "mutate through ptr initialized with constant ptrFromInt value" {
1719 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1820 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1921 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
22 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2023
2124 forceCompilerAnalyzeBranchHardCodedPtrDereference(false);
2225}
......@@ -34,6 +37,7 @@ test "@ptrFromInt creates null pointer" {
3437 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3538 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3639 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
40 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3741
3842 const ptr = @as(?*u32, @ptrFromInt(0));
3943 try expectEqual(@as(?*u32, null), ptr);
......@@ -43,6 +47,7 @@ test "@ptrFromInt creates allowzero zero pointer" {
4347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
4448 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
4549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4651
4752 const ptr = @as(*allowzero u32, @ptrFromInt(0));
4853 try expectEqual(@as(usize, 0), @intFromPtr(ptr));
test/behavior/pub_enum.zig+2
......@@ -4,6 +4,7 @@ const expect = @import("std").testing.expect;
44
55test "pub enum" {
66 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
78
89 try pubEnumTest(other.APubEnum.Two);
910}
......@@ -13,6 +14,7 @@ fn pubEnumTest(foo: other.APubEnum) !void {
1314
1415test "cast with imported symbol" {
1516 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
17 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1618
1719 try expect(@as(other.size_t, 42) == 42);
1820}
test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig+1
......@@ -8,6 +8,7 @@ test "reference a variable in an if after an if in the 2nd switch prong" {
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1112
1213 try foo(true, Num.Two, false, "aoeu");
1314 try expect(!ok);
test/behavior/reflection.zig+1
......@@ -28,6 +28,7 @@ fn dummy(a: bool, b: i32, c: f32) i32 {
2828test "reflection: @field" {
2929 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3030 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
31 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3132
3233 var f = Foo{
3334 .one = 42,
test/behavior/return_address.zig+1
......@@ -10,6 +10,7 @@ test "return address" {
1010 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1212 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1314
1415 _ = retAddr();
1516 // TODO: #14938
test/behavior/saturating_arithmetic.zig+7
......@@ -9,6 +9,7 @@ test "saturating add" {
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1213
1314 const S = struct {
1415 fn doTheTest() !void {
......@@ -57,6 +58,7 @@ test "saturating add 128bit" {
5758 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5859 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5960 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
61 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6062
6163 const S = struct {
6264 fn doTheTest() !void {
......@@ -82,6 +84,7 @@ test "saturating subtraction" {
8284 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8385 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8486 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
87 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8588
8689 const S = struct {
8790 fn doTheTest() !void {
......@@ -129,6 +132,7 @@ test "saturating subtraction 128bit" {
129132 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
130133 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
131134 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
135 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
132136
133137 const S = struct {
134138 fn doTheTest() !void {
......@@ -158,6 +162,7 @@ test "saturating multiplication" {
158162 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
159163 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
160164 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
165 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
161166
162167 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) {
163168 // https://github.com/ziglang/zig/issues/9660
......@@ -203,6 +208,7 @@ test "saturating shift-left" {
203208 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
204209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
205210 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
211 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
206212
207213 const S = struct {
208214 fn doTheTest() !void {
......@@ -243,6 +249,7 @@ test "saturating shl uses the LHS type" {
243249 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
244250 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
245251 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
246253
247254 const lhs_const: u8 = 1;
248255 var lhs_var: u8 = 1;
test/behavior/select.zig+2
......@@ -9,6 +9,7 @@ test "@select vectors" {
99 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1213
1314 try comptime selectVectors();
1415 try selectVectors();
......@@ -39,6 +40,7 @@ test "@select arrays" {
3940 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4041 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4142 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
43 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4244 if (builtin.zig_backend == .stage2_x86_64 and
4345 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return error.SkipZigTest;
4446
test/behavior/shuffle.zig+3
......@@ -7,6 +7,7 @@ test "@shuffle int" {
77 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011 if (builtin.zig_backend == .stage2_x86_64 and
1112 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .ssse3)) return error.SkipZigTest;
1213
......@@ -54,6 +55,7 @@ test "@shuffle bool 1" {
5455 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5556 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5657 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5759
5860 if (builtin.zig_backend == .stage2_llvm and
5961 builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows)
......@@ -83,6 +85,7 @@ test "@shuffle bool 2" {
8385 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8486 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8587 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8689
8790 if (builtin.zig_backend == .stage2_llvm) {
8891 // https://github.com/ziglang/zig/issues/3246
test/behavior/sizeof_and_typeof.zig+5
......@@ -81,6 +81,7 @@ const P = packed struct {
8181test "@offsetOf" {
8282 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8383 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
84 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8485
8586 // Packed structs have fixed memory layout
8687 try expect(@offsetOf(P, "a") == 0);
......@@ -157,6 +158,7 @@ test "@TypeOf() has no runtime side effects" {
157158
158159test "branching logic inside @TypeOf" {
159160 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
161 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
160162
161163 const S = struct {
162164 var data: i32 = 0;
......@@ -271,6 +273,7 @@ test "runtime instructions inside typeof in comptime only scope" {
271273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
272274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
273275 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
276 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
274277
275278 {
276279 var y: i8 = 2;
......@@ -327,6 +330,7 @@ test "peer type resolution with @TypeOf doesn't trigger dependency loop check" {
327330 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
328331 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
329332 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
333 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
330334
331335 const T = struct {
332336 next: @TypeOf(null, @as(*const @This(), undefined)),
......@@ -408,6 +412,7 @@ test "Extern function calls, dereferences and field access in @TypeOf" {
408412 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
409413 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
410414 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
415 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
411416
412417 const Test = struct {
413418 fn test_fn_1(a: c_long) @TypeOf(c_fopen("test", "r").*) {
test/behavior/slice.zig+30
......@@ -30,6 +30,7 @@ comptime {
3030
3131test "slicing" {
3232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
33 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3334
3435 var array: [20]i32 = undefined;
3536
......@@ -66,6 +67,7 @@ test "comptime slice of undefined pointer of length 0" {
6667
6768test "implicitly cast array of size 0 to slice" {
6869 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6971
7072 var msg = [_]u8{};
7173 try assertLenIsZero(&msg);
......@@ -122,6 +124,7 @@ test "slice of type" {
122124
123125test "generic malloc free" {
124126 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
125128
126129 const a = memAlloc(u8, 10) catch unreachable;
127130 memFree(u8, a);
......@@ -183,6 +186,8 @@ test "slicing zero length array" {
183186}
184187
185188test "slicing pointer by length" {
189 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
190
186191 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
187192 const ptr: [*]const u8 = @as([*]const u8, @ptrCast(&array));
188193 const slice = ptr[1..][0..5];
......@@ -231,6 +236,7 @@ test "runtime safety lets us slice from len..len" {
231236 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
232237 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
233238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
239 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
234240
235241 var an_array = [_]u8{ 1, 2, 3 };
236242 try expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
......@@ -243,6 +249,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
243249test "C pointer" {
244250 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
245251 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
246253
247254 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
248255 var len: u32 = 10;
......@@ -255,6 +262,7 @@ test "C pointer slice access" {
255262 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
256263 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
257264 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
265 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
258266
259267 var buf: [10]u32 = [1]u32{42} ** 10;
260268 const c_ptr = @as([*c]const u32, @ptrCast(&buf));
......@@ -285,6 +293,7 @@ fn sliceSum(comptime q: []const u8) i32 {
285293test "slice type with custom alignment" {
286294 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
287295 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
296 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
288297
289298 const LazilyResolvedType = struct {
290299 anything: i32,
......@@ -298,6 +307,7 @@ test "slice type with custom alignment" {
298307
299308test "obtaining a null terminated slice" {
300309 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
310 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
301311
302312 // here we have a normal array
303313 var buf: [50]u8 = undefined;
......@@ -342,6 +352,7 @@ test "empty array to slice" {
342352test "@ptrCast slice to pointer" {
343353 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
344354 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
355 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
345356
346357 const S = struct {
347358 fn doTheTest() !void {
......@@ -357,6 +368,8 @@ test "@ptrCast slice to pointer" {
357368}
358369
359370test "slice multi-pointer without end" {
371 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
372
360373 const S = struct {
361374 fn doTheTest() !void {
362375 try testPointer();
......@@ -394,6 +407,7 @@ test "slice syntax resulting in pointer-to-array" {
394407 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
395408 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
396409 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
410 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
397411
398412 const S = struct {
399413 fn doTheTest() !void {
......@@ -612,6 +626,7 @@ test "slice syntax resulting in pointer-to-array" {
612626test "slice pointer-to-array null terminated" {
613627 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
614628 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
629 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
615630
616631 comptime {
617632 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
......@@ -630,6 +645,7 @@ test "slice pointer-to-array null terminated" {
630645
631646test "slice pointer-to-array zero length" {
632647 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
648 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
633649
634650 comptime {
635651 {
......@@ -664,6 +680,7 @@ test "type coercion of pointer to anon struct literal to pointer to slice" {
664680 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
665681 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
666682 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
683 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
667684
668685 const S = struct {
669686 const U = union {
......@@ -755,6 +772,7 @@ test "slice sentinel access at comptime" {
755772test "slicing array with sentinel as end index" {
756773 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
757774 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
775 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
758776
759777 const S = struct {
760778 fn do() !void {
......@@ -773,6 +791,7 @@ test "slicing array with sentinel as end index" {
773791test "slicing slice with sentinel as end index" {
774792 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
775793 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
794 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
776795
777796 const S = struct {
778797 fn do() !void {
......@@ -831,6 +850,7 @@ test "global slice field access" {
831850 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
832851 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
833852 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
853 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
834854
835855 const S = struct {
836856 var slice: []const u8 = undefined;
......@@ -842,6 +862,8 @@ test "global slice field access" {
842862}
843863
844864test "slice of void" {
865 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
866
845867 var n: usize = 10;
846868 _ = &n;
847869 var arr: [12]void = undefined;
......@@ -850,6 +872,8 @@ test "slice of void" {
850872}
851873
852874test "slice with dereferenced value" {
875 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
876
853877 var a: usize = 0;
854878 const idx: *usize = &a;
855879 _ = blk: {
......@@ -884,6 +908,7 @@ test "empty slice ptr is non null" {
884908test "slice decays to many pointer" {
885909 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
886910 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
911 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
887912
888913 var buf: [8]u8 = "abcdefg\x00".*;
889914 const p: [*:0]const u8 = buf[0..7 :0];
......@@ -894,6 +919,7 @@ test "write through pointer to optional slice arg" {
894919 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
895920 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
896921 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
922 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
897923
898924 const S = struct {
899925 fn bar(foo: *?[]const u8) !void {
......@@ -930,6 +956,7 @@ test "slicing zero length array field of struct" {
930956 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
931957 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
932958 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
959 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
933960
934961 const S = struct {
935962 a: [0]usize,
......@@ -945,6 +972,7 @@ test "slicing slices gives correct result" {
945972 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
946973 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
947974 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
975 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
948976
949977 const foo = "1234";
950978 const bar = foo[0..4];
......@@ -959,6 +987,7 @@ test "get address of element of zero-sized slice" {
959987 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
960988 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
961989 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
990 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
962991
963992 const S = struct {
964993 fn destroy(_: *void) void {}
......@@ -972,6 +1001,7 @@ test "sentinel-terminated 0-length slices" {
9721001 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
9731002 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9741003 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1004 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9751005
9761006 const u32s: [4]u32 = [_]u32{ 0, 1, 2, 3 };
9771007
test/behavior/src.zig+3
......@@ -17,6 +17,7 @@ test "@src" {
1717 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1818 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1919 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2021
2122 try doTheTest();
2223}
......@@ -37,6 +38,8 @@ test "@src used as a comptime parameter" {
3738}
3839
3940test "@src in tuple passed to anytype function" {
41 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
42
4043 const S = struct {
4144 fn Foo(a: anytype) u32 {
4245 return a[0].line;
test/behavior/string_literals.zig+3
......@@ -34,6 +34,7 @@ const ptr_type_name: [*:0]const u8 = type_name;
3434test "@typeName() returns a string literal" {
3535 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3636 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3738
3839 try std.testing.expect(*const [type_name.len:0]u8 == @TypeOf(type_name));
3940 try std.testing.expect(std.mem.eql(u8, "behavior.string_literals.TestType", type_name));
......@@ -47,6 +48,7 @@ const expected_contents = "hello zig\n";
4748test "@embedFile() returns a string literal" {
4849 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4950 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5052
5153 try std.testing.expect(*const [expected_contents.len:0]u8 == @TypeOf(actual_contents));
5254 try std.testing.expect(std.mem.eql(u8, expected_contents, actual_contents));
......@@ -61,6 +63,7 @@ fn testFnForSrc() std.builtin.SourceLocation {
6163test "@src() returns a struct containing 0-terminated string slices" {
6264 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6365 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
66 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6467
6568 const src = testFnForSrc();
6669 try std.testing.expect([:0]const u8 == @TypeOf(src.file));
test/behavior/struct.zig+75
......@@ -68,6 +68,7 @@ const SmallStruct = struct {
6868
6969test "lower unnamed constants" {
7070 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
71 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7172
7273 var foo = SmallStruct{ .a = 1, .b = 255 };
7374 try expect(foo.first() == 1);
......@@ -91,6 +92,7 @@ test "structs" {
9192 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9293 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9394 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
95 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9496
9597 var foo: StructFoo = undefined;
9698 @memset(@as([*]u8, @ptrCast(&foo))[0..@sizeOf(StructFoo)], 0);
......@@ -109,6 +111,7 @@ fn testMutation(foo: *StructFoo) void {
109111
110112test "struct byval assign" {
111113 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
114 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
112115
113116 var foo1: StructFoo = undefined;
114117 var foo2: StructFoo = undefined;
......@@ -173,6 +176,7 @@ const MemberFnTestFoo = struct {
173176
174177test "call member function directly" {
175178 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
179 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
176180
177181 const instance = MemberFnTestFoo{ .x = 1234 };
178182 const result = MemberFnTestFoo.member(instance);
......@@ -181,6 +185,7 @@ test "call member function directly" {
181185
182186test "store member function in variable" {
183187 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
188 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
184189
185190 const instance = MemberFnTestFoo{ .x = 1234 };
186191 const memberFn = MemberFnTestFoo.member;
......@@ -202,6 +207,7 @@ const MemberFnRand = struct {
202207test "return struct byval from function" {
203208 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
204209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
210 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
205211
206212 const Bar = struct {
207213 x: i32,
......@@ -250,6 +256,7 @@ test "usingnamespace within struct scope" {
250256test "struct field init with catch" {
251257 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
252258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
259 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
253260
254261 const S = struct {
255262 fn doTheTest() !void {
......@@ -293,6 +300,7 @@ const Val = struct {
293300test "struct point to self" {
294301 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
295302 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
303 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
296304
297305 var root: Node = undefined;
298306 root.val.x = 1;
......@@ -347,6 +355,7 @@ test "self-referencing struct via array member" {
347355 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
348356 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
349357 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
358 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
350359
351360 const T = struct {
352361 children: [1]*@This(),
......@@ -369,6 +378,7 @@ const EmptyStruct = struct {
369378
370379test "align 1 field before self referential align 8 field as slice return type" {
371380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
381 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
372382
373383 const result = alloc(Expr);
374384 try expect(result.len == 0);
......@@ -393,6 +403,7 @@ test "packed struct" {
393403 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
394404 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
395405 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
406 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
396407
397408 var foo = APackedStruct{
398409 .x = 1,
......@@ -417,6 +428,7 @@ test "packed struct 24bits" {
417428 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
418429 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
419430 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
431 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
420432 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO
421433 if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO
422434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -463,6 +475,7 @@ test "runtime struct initialization of bitfield" {
463475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
464476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
465477 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
478 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
466479
467480 const s1 = Nibbles{
468481 .x = x1,
......@@ -502,6 +515,7 @@ test "packed struct fields are ordered from LSB to MSB" {
502515 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
503516 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
504517 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
518 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
505519
506520 var all: u64 = 0x7765443322221111;
507521 var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined;
......@@ -522,6 +536,7 @@ test "implicit cast packed struct field to const ptr" {
522536 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
523537 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
524538 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
539 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
525540
526541 const LevelUpMove = packed struct {
527542 move_id: u9,
......@@ -557,6 +572,7 @@ test "packed struct with non-ABI-aligned field" {
557572 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
558573 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
559574 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
575 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
560576
561577 const S = packed struct {
562578 x: u9,
......@@ -586,6 +602,7 @@ test "bit field access" {
586602 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
587603 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
588604 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
605 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
589606
590607 var data = bit_field_1;
591608 try expect(getA(&data) == 1);
......@@ -616,6 +633,7 @@ fn getC(data: *const BitField1) u2 {
616633test "default struct initialization fields" {
617634 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
618635 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
636 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
619637
620638 const S = struct {
621639 a: i32 = 1234,
......@@ -642,6 +660,7 @@ test "packed array 24bits" {
642660 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
643661 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
644662 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
663 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
645664
646665 comptime {
647666 try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
......@@ -709,6 +728,7 @@ test "pointer to packed struct member in a stack variable" {
709728 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
710729 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
711730 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
731 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
712732
713733 const S = packed struct {
714734 a: u2,
......@@ -761,6 +781,7 @@ test "packed struct with fp fields" {
761781 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
762782 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
763783 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
784 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
764785
765786 const S = packed struct {
766787 data0: f32,
......@@ -788,6 +809,7 @@ test "fn with C calling convention returns struct by value" {
788809 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
789810 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
790811 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
812 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
791813
792814 const S = struct {
793815 fn entry() !void {
......@@ -815,6 +837,7 @@ test "non-packed struct with u128 entry in union" {
815837 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
816838 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
817839 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
840 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
818841
819842 const U = union(enum) {
820843 Num: u128,
......@@ -863,6 +886,7 @@ test "packed struct field passed to generic function" {
863886test "anonymous struct literal syntax" {
864887 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
865888 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
889 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
866890
867891 const S = struct {
868892 const Point = struct {
......@@ -885,6 +909,8 @@ test "anonymous struct literal syntax" {
885909}
886910
887911test "fully anonymous struct" {
912 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
913
888914 const S = struct {
889915 fn doTheTest() !void {
890916 try dump(.{
......@@ -907,6 +933,8 @@ test "fully anonymous struct" {
907933}
908934
909935test "fully anonymous list literal" {
936 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
937
910938 const S = struct {
911939 fn doTheTest() !void {
912940 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
......@@ -954,6 +982,7 @@ test "tuple element initialized with fn call" {
954982 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
955983 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
956984 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
985 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
957986
958987 const S = struct {
959988 fn doTheTest() !void {
......@@ -972,6 +1001,7 @@ test "struct with union field" {
9721001 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9731002 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9741003 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1004 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9751005
9761006 const Value = struct {
9771007 ref: u32 = 2,
......@@ -993,6 +1023,7 @@ test "struct with 0-length union array field" {
9931023 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9941024 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9951025 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1026 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9961027
9971028 const U = union {
9981029 a: u32,
......@@ -1013,6 +1044,7 @@ test "type coercion of anon struct literal to struct" {
10131044 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10141045 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10151046 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1047 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10161048
10171049 const S = struct {
10181050 const S2 = struct {
......@@ -1052,6 +1084,7 @@ test "type coercion of pointer to anon struct literal to pointer to struct" {
10521084 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10531085 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10541086 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1087 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10551088
10561089 const S = struct {
10571090 const S2 = struct {
......@@ -1091,6 +1124,7 @@ test "packed struct with undefined initializers" {
10911124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10921125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10931126 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10941128
10951129 const S = struct {
10961130 const P = packed struct {
......@@ -1120,6 +1154,7 @@ test "packed struct with undefined initializers" {
11201154test "for loop over pointers to struct, getting field from struct pointer" {
11211155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11221156 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1157 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11231158
11241159 const S = struct {
11251160 const Foo = struct {
......@@ -1160,6 +1195,7 @@ test "anon init through error unions and optionals" {
11601195 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11611196 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11621197 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1198 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11631199
11641200 const S = struct {
11651201 a: u32,
......@@ -1187,6 +1223,7 @@ test "anon init through optional" {
11871223 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11881224 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11891225 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1226 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11901227
11911228 const S = struct {
11921229 a: u32,
......@@ -1207,6 +1244,7 @@ test "anon init through error union" {
12071244 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12081245 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12091246 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1247 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12101248
12111249 const S = struct {
12121250 a: u32,
......@@ -1226,6 +1264,7 @@ test "typed init through error unions and optionals" {
12261264 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12271265 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12281266 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1267 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12291268
12301269 const S = struct {
12311270 a: u32,
......@@ -1260,6 +1299,7 @@ test "initialize struct with empty literal" {
12601299
12611300test "loading a struct pointer perfoms a copy" {
12621301 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1302 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12631303
12641304 const S = struct {
12651305 a: i32,
......@@ -1288,6 +1328,7 @@ test "packed struct aggregate init" {
12881328 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12891329 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12901330 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1331 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12911332
12921333 const S = struct {
12931334 fn foo(a: i2, b: i6) u8 {
......@@ -1347,6 +1388,7 @@ test "store to comptime field" {
13471388test "struct field init value is size of the struct" {
13481389 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13491390 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1391 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13501392
13511393 const namespace = struct {
13521394 const S = extern struct {
......@@ -1364,6 +1406,7 @@ test "under-aligned struct field" {
13641406 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13651407 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13661408 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1409 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13671410
13681411 const U = extern union {
13691412 fd: i32,
......@@ -1386,6 +1429,7 @@ test "fieldParentPtr of a zero-bit field" {
13861429 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13871430 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13881431 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1432 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13891433
13901434 const S = struct {
13911435 fn testStruct(comptime A: type) !void {
......@@ -1444,6 +1488,8 @@ test "struct field has a pointer to an aligned version of itself" {
14441488}
14451489
14461490test "struct has only one reference" {
1491 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1492
14471493 const S = struct {
14481494 fn optionalStructParam(_: ?struct { x: u8 }) void {}
14491495 fn errorUnionStructParam(_: error{}!struct { x: u8 }) void {}
......@@ -1493,6 +1539,7 @@ test "no dependency loop on pointer to optional struct" {
14931539 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
14941540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14951541 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1542 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14961543
14971544 const S = struct {
14981545 const A = struct { b: B };
......@@ -1514,6 +1561,7 @@ test "discarded struct initialization works as expected" {
15141561test "function pointer in struct returns the struct" {
15151562 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15161563 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1564 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15171565
15181566 const A = struct {
15191567 const A = @This();
......@@ -1549,6 +1597,7 @@ test "no dependency loop on optional field wrapped in generic function" {
15491597test "optional field init with tuple" {
15501598 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15511599 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1600 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15521601
15531602 const S = struct {
15541603 a: ?struct { b: u32 },
......@@ -1563,6 +1612,7 @@ test "optional field init with tuple" {
15631612
15641613test "if inside struct init inside if" {
15651614 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1615 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15661616
15671617 const MyStruct = struct { x: u32 };
15681618 const b: u32 = 5;
......@@ -1682,6 +1732,7 @@ test "extern struct field pointer has correct alignment" {
16821732 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16831733 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16841734 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1735 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16851736
16861737 const S = struct {
16871738 fn doTheTest() !void {
......@@ -1719,6 +1770,8 @@ test "extern struct field pointer has correct alignment" {
17191770}
17201771
17211772test "packed struct field in anonymous struct" {
1773 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1774
17221775 const T = packed struct {
17231776 f1: bool = false,
17241777 };
......@@ -1730,6 +1783,8 @@ fn countFields(v: anytype) usize {
17301783}
17311784
17321785test "struct init with no result pointer sets field result types" {
1786 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1787
17331788 const S = struct {
17341789 // A function parameter has a result type, but no result pointer.
17351790 fn f(s: struct { x: u32 }) u32 {
......@@ -1744,6 +1799,8 @@ test "struct init with no result pointer sets field result types" {
17441799}
17451800
17461801test "runtime side-effects in comptime-known struct init" {
1802 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1803
17471804 var side_effects: u4 = 0;
17481805 const S = struct { a: u4, b: u4, c: u4, d: u4 };
17491806 const init = S{
......@@ -1769,6 +1826,8 @@ test "runtime side-effects in comptime-known struct init" {
17691826}
17701827
17711828test "pointer to struct initialized through reference to anonymous initializer provides result types" {
1829 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1830
17721831 const S = struct { a: u8, b: u16, c: *const anyopaque };
17731832 var my_u16: u16 = 0xABCD;
17741833 _ = &my_u16;
......@@ -1804,6 +1863,8 @@ test "comptimeness of optional and error union payload is analyzed properly" {
18041863}
18051864
18061865test "initializer uses own alignment" {
1866 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1867
18071868 const S = struct {
18081869 x: u32 = @alignOf(@This()) + 1,
18091870 };
......@@ -1815,6 +1876,8 @@ test "initializer uses own alignment" {
18151876}
18161877
18171878test "initializer uses own size" {
1879 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1880
18181881 const S = struct {
18191882 x: u32 = @sizeOf(@This()) + 1,
18201883 };
......@@ -1826,6 +1889,8 @@ test "initializer uses own size" {
18261889}
18271890
18281891test "initializer takes a pointer to a variable inside its struct" {
1892 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1893
18291894 const namespace = struct {
18301895 const S = struct {
18311896 s: *S = &S.instance,
......@@ -1844,6 +1909,8 @@ test "initializer takes a pointer to a variable inside its struct" {
18441909}
18451910
18461911test "circular dependency through pointer field of a struct" {
1912 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1913
18471914 const S = struct {
18481915 const StructInner = extern struct {
18491916 outer: StructOuter = std.mem.zeroes(StructOuter),
......@@ -1865,6 +1932,8 @@ test "circular dependency through pointer field of a struct" {
18651932}
18661933
18671934test "field calls do not force struct field init resolution" {
1935 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1936
18681937 const S = struct {
18691938 x: u32 = blk: {
18701939 _ = @TypeOf(make().dummyFn()); // runtime field call - S not fully resolved - dummyFn call should not force field init resolution
......@@ -1914,6 +1983,7 @@ test "assign to slice.len of global variable" {
19141983 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19151984 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
19161985 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1986 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19171987
19181988 const S = struct {
19191989 const allocator = std.testing.allocator;
......@@ -1964,6 +2034,7 @@ test "runtime call in nested initializer" {
19642034 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
19652035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
19662036 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2037 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19672038
19682039 const Holder = struct {
19692040 array: []const u8,
......@@ -1996,6 +2067,7 @@ test "runtime value in nested initializer passed as pointer to function" {
19962067 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
19972068 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
19982069 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2070 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19992071
20002072 const Bar = struct {
20012073 b: u32,
......@@ -2070,6 +2142,7 @@ test "assignment of field with padding" {
20702142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
20712143 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
20722144 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2145 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20732146
20742147 const Mesh = extern struct {
20752148 id: u32,
......@@ -2100,6 +2173,7 @@ test "initiate global variable with runtime value" {
21002173 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
21012174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
21022175 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2176 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21032177
21042178 const S = struct {
21052179 field: i32,
......@@ -2118,6 +2192,7 @@ test "initiate global variable with runtime value" {
21182192test "struct containing optional pointer to array of @This()" {
21192193 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
21202194 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2195 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21212196
21222197 const S = struct {
21232198 x: ?*const [1]@This(),
test/behavior/struct_contains_null_ptr_itself.zig+1
......@@ -5,6 +5,7 @@ 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;
89
910 var x: ?*NodeLineComment = null;
1011 _ = &x;
test/behavior/struct_contains_slice_of_itself.zig+2
......@@ -13,6 +13,7 @@ const NodeAligned = struct {
1313
1414test "struct contains slice of itself" {
1515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1617
1718 var other_nodes = [_]Node{
1819 Node{
......@@ -53,6 +54,7 @@ test "struct contains slice of itself" {
5354test "struct contains aligned slice of itself" {
5455 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5556 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5658
5759 var other_nodes = [_]NodeAligned{
5860 NodeAligned{
test/behavior/switch.zig+43
......@@ -7,6 +7,7 @@ const expectEqual = std.testing.expectEqual;
77
88test "switch with numbers" {
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011
1112 try testSwitchWithNumbers(13);
1213}
......@@ -22,6 +23,7 @@ fn testSwitchWithNumbers(x: u32) !void {
2223
2324test "switch with all ranges" {
2425 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2527
2628 try expect(testSwitchWithAllRanges(50, 3) == 1);
2729 try expect(testSwitchWithAllRanges(101, 0) == 2);
......@@ -55,6 +57,7 @@ test "implicit comptime switch" {
5557
5658test "switch on enum" {
5759 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5861
5962 const fruit = Fruit.Orange;
6063 nonConstSwitchOnEnum(fruit);
......@@ -74,6 +77,7 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {
7477
7578test "switch statement" {
7679 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7781
7882 try nonConstSwitch(SwitchStatementFoo.C);
7983}
......@@ -90,6 +94,7 @@ const SwitchStatementFoo = enum { A, B, C, D };
9094
9195test "switch with multiple expressions" {
9296 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9398
9499 const x = switch (returnsFive()) {
95100 1, 2, 3 => 1,
......@@ -118,6 +123,7 @@ fn trueIfBoolFalseOtherwise(comptime T: type) bool {
118123
119124test "switching on booleans" {
120125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
121127
122128 try testSwitchOnBools();
123129 try comptime testSwitchOnBools();
......@@ -173,6 +179,7 @@ test "undefined.u0" {
173179
174180test "switch with disjoint range" {
175181 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
176183
177184 var q: u8 = 0;
178185 _ = &q;
......@@ -184,6 +191,8 @@ test "switch with disjoint range" {
184191}
185192
186193test "switch variable for range and multiple prongs" {
194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
195
187196 const S = struct {
188197 fn doTheTest() !void {
189198 try doTheSwitch(16);
......@@ -215,6 +224,7 @@ fn poll() void {
215224
216225test "switch on global mutable var isn't constant-folded" {
217226 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
227 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
218228
219229 while (state < 2) {
220230 poll();
......@@ -231,6 +241,7 @@ test "switch prong with variable" {
231241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
232242 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
233243 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
244 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
234245
235246 try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
236247 try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
......@@ -255,6 +266,7 @@ test "switch on enum using pointer capture" {
255266 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256267 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
257268 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
269 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
258270
259271 try testSwitchEnumPtrCapture();
260272 try comptime testSwitchEnumPtrCapture();
......@@ -274,6 +286,7 @@ fn testSwitchEnumPtrCapture() !void {
274286
275287test "switch handles all cases of number" {
276288 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
289 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
277290
278291 try testSwitchHandleAllCases();
279292 try comptime testSwitchHandleAllCases();
......@@ -315,6 +328,7 @@ test "switch on union with some prongs capturing" {
315328 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
316329 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
317330 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
331 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
318332
319333 const X = union(enum) {
320334 a,
......@@ -368,6 +382,7 @@ test "anon enum literal used in switch on union enum" {
368382
369383test "switch all prongs unreachable" {
370384 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
385 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
371386
372387 try testAllProngsUnreachable();
373388 try comptime testAllProngsUnreachable();
......@@ -391,6 +406,7 @@ fn switchWithUnreachable(x: i32) i32 {
391406
392407test "capture value of switch with all unreachable prongs" {
393408 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
394410
395411 const x = return_a_number() catch |err| switch (err) {
396412 else => unreachable,
......@@ -404,6 +420,7 @@ fn return_a_number() anyerror!i32 {
404420
405421test "switch on integer with else capturing expr" {
406422 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
423 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
407424
408425 const S = struct {
409426 fn doTheTest() !void {
......@@ -425,6 +442,7 @@ test "else prong of switch on error set excludes other cases" {
425442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
426443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
427444 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
445 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
428446
429447 const S = struct {
430448 fn doTheTest() !void {
......@@ -460,6 +478,7 @@ test "switch prongs with error set cases make a new error set type for capture v
460478 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
461479 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
462480 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
481 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
463482
464483 const S = struct {
465484 fn doTheTest() !void {
......@@ -494,6 +513,7 @@ test "switch prongs with error set cases make a new error set type for capture v
494513
495514test "return result loc and then switch with range implicit casted to error union" {
496515 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
516 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
497517
498518 const S = struct {
499519 fn doTheTest() !void {
......@@ -514,6 +534,7 @@ test "switch with null and T peer types and inferred result location type" {
514534 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
515535 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
516536 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
537 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
517538
518539 const S = struct {
519540 fn doTheTest(c: u8) !void {
......@@ -534,6 +555,7 @@ test "switch prongs with cases with identical payload types" {
534555 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
535556 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
536557 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
558 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
537559
538560 const Union = union(enum) {
539561 A: usize,
......@@ -640,6 +662,7 @@ test "switch prong pointer capture alignment" {
640662test "switch on pointer type" {
641663 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
642664 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
665 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
643666
644667 const S = struct {
645668 const X = struct {
......@@ -688,6 +711,7 @@ test "switch capture copies its payload" {
688711 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
689712 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
690713 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
714 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
691715
692716 const S = struct {
693717 fn doTheTest() !void {
......@@ -711,6 +735,7 @@ test "switch capture copies its payload" {
711735
712736test "capture of integer forwards the switch condition directly" {
713737 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
738 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
714739
715740 const S = struct {
716741 fn foo(x: u8) !void {
......@@ -732,6 +757,7 @@ test "capture of integer forwards the switch condition directly" {
732757
733758test "enum value without tag name used as switch item" {
734759 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
760 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
735761
736762 const E = enum(u32) {
737763 a = 1,
......@@ -749,6 +775,8 @@ test "enum value without tag name used as switch item" {
749775}
750776
751777test "switch item sizeof" {
778 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
779
752780 const S = struct {
753781 fn doTheTest() !void {
754782 var a: usize = 0;
......@@ -777,6 +805,8 @@ test "comptime inline switch" {
777805}
778806
779807test "switch capture peer type resolution" {
808 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
809
780810 const U = union(enum) {
781811 a: u32,
782812 b: u64,
......@@ -792,6 +822,8 @@ test "switch capture peer type resolution" {
792822}
793823
794824test "switch capture peer type resolution for in-memory coercible payloads" {
825 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
826
795827 const T1 = c_int;
796828 const T2 = @Type(@typeInfo(T1));
797829
......@@ -813,6 +845,7 @@ test "switch capture peer type resolution for in-memory coercible payloads" {
813845
814846test "switch pointer capture peer type resolution" {
815847 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
848 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
816849
817850 const T1 = c_int;
818851 const T2 = @Type(@typeInfo(T1));
......@@ -840,6 +873,8 @@ test "switch pointer capture peer type resolution" {
840873}
841874
842875test "inline switch range that includes the maximum value of the switched type" {
876 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
877
843878 const inputs: [3]u8 = .{ 0, 254, 255 };
844879 for (inputs) |input| {
845880 switch (input) {
......@@ -850,6 +885,8 @@ test "inline switch range that includes the maximum value of the switched type"
850885}
851886
852887test "nested break ignores switch conditions and breaks instead" {
888 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
889
853890 const S = struct {
854891 fn register_to_address(ident: []const u8) !u8 {
855892 const reg: u8 = if (std.mem.eql(u8, ident, "zero")) 0x00 else blk: {
......@@ -870,6 +907,7 @@ test "nested break ignores switch conditions and breaks instead" {
870907
871908test "peer type resolution on switch captures ignores unused payload bits" {
872909 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
910 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
873911
874912 const Foo = union(enum) {
875913 a: u32,
......@@ -895,6 +933,7 @@ test "peer type resolution on switch captures ignores unused payload bits" {
895933test "switch prong captures range" {
896934 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
897935 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
936 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
898937
899938 const S = struct {
900939 fn a(b: []u3, c: u3) void {
......@@ -912,6 +951,8 @@ test "switch prong captures range" {
912951}
913952
914953test "prong with inline call to unreachable" {
954 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
955
915956 const U = union(enum) {
916957 void: void,
917958 bool: bool,
......@@ -929,6 +970,8 @@ test "prong with inline call to unreachable" {
929970}
930971
931972test "block error return trace index is reset between prongs" {
973 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
974
932975 const S = struct {
933976 fn returnError() error{TestFailed} {
934977 return error.TestFailed;
test/behavior/switch_on_captured_error.zig+2
......@@ -8,6 +8,7 @@ const builtin = @import("builtin");
88test "switch on error union catch capture" {
99 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1010 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1112
1213 const S = struct {
1314 const Error = error{ A, B, C };
......@@ -302,6 +303,7 @@ test "switch on error union catch capture" {
302303test "switch on error union if else capture" {
303304 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
304305 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
306 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
305307
306308 const S = struct {
307309 const Error = error{ A, B, C };
test/behavior/switch_prong_err_enum.zig+1
......@@ -24,6 +24,7 @@ test "switch prong returns error enum" {
2424 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2525 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2626 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2728
2829 switch (doThing(17) catch unreachable) {
2930 FormValue.Address => |payload| {
test/behavior/switch_prong_implicit_cast.zig+1
......@@ -18,6 +18,7 @@ test "switch prong implicit cast" {
1818 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1919 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2020 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
21 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2122
2223 const result = switch (foo(2) catch unreachable) {
2324 FormValue.One => false,
test/behavior/this.zig+2
......@@ -27,6 +27,7 @@ test "this refer to module call private fn" {
2727test "this refer to container" {
2828 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2929 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
30 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3031
3132 var pt: Point(i32) = undefined;
3233 pt.x = 12;
......@@ -50,6 +51,7 @@ test "this used as optional function parameter" {
5051 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5152 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5253 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
54 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5355
5456 var global: State = undefined;
5557 global.enter = prev;
test/behavior/threadlocal.zig+3
......@@ -6,6 +6,7 @@ test "thread local variable" {
66 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
1011 .x86_64, .x86 => {},
1112 else => return error.SkipZigTest,
......@@ -28,6 +29,7 @@ test "pointer to thread local array" {
2829 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2930 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3031 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3133 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
3234 .x86_64, .x86 => {},
3335 else => return error.SkipZigTest,
......@@ -45,6 +47,7 @@ test "reference a global threadlocal variable" {
4547 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
4648 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4749 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4851 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
4952 .x86_64, .x86 => {},
5053 else => return error.SkipZigTest,
test/behavior/truncate.zig+1
......@@ -69,6 +69,7 @@ test "truncate on vectors" {
6969 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7070 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7171 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7273
7374 const S = struct {
7475 fn doTheTest() !void {
test/behavior/try.zig+2
......@@ -4,6 +4,7 @@ const expect = std.testing.expect;
44
55test "try on error union" {
66 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
78
89 try tryOnErrorUnionImpl();
910 try comptime tryOnErrorUnionImpl();
......@@ -51,6 +52,7 @@ test "`try`ing an if/else expression" {
5152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5354 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
55 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5456
5557 const S = struct {
5658 fn getError() !void {
test/behavior/tuple.zig+19
......@@ -10,6 +10,7 @@ test "tuple concatenation" {
1010 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1111 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1314
1415 const S = struct {
1516 fn doTheTest() !void {
......@@ -55,6 +56,7 @@ test "more tuple concatenation" {
5556 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5657 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5758 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
59 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5860
5961 const T = struct {
6062 fn consume_tuple(tuple: anytype, len: usize) !void {
......@@ -131,6 +133,7 @@ test "tuple initializer for var" {
131133test "array-like initializer for tuple types" {
132134 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
133135 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
136 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
134137
135138 const T = @Type(.{
136139 .Struct = .{
......@@ -218,6 +221,7 @@ test "fieldParentPtr of tuple" {
218221 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
219222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
220223 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
224 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
221225
222226 var x: u32 = 0;
223227 _ = &x;
......@@ -229,6 +233,7 @@ test "fieldParentPtr of anon struct" {
229233 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
230234 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
231235 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
236 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
232237
233238 var x: u32 = 0;
234239 _ = &x;
......@@ -278,6 +283,7 @@ test "tuple in tuple passed to generic function" {
278283 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
279284 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
280285 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
286 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
281287
282288 const S = struct {
283289 fn pair(x: f32, y: f32) std.meta.Tuple(&.{ f32, f32 }) {
......@@ -297,6 +303,7 @@ test "coerce tuple to tuple" {
297303 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
298304 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
299305 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
300307
301308 const T = std.meta.Tuple(&.{u8});
302309 const S = struct {
......@@ -311,6 +318,7 @@ test "tuple type with void field" {
311318 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
312319 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
313320 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
321 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
314322
315323 const T = std.meta.Tuple(&[_]type{void});
316324 const x = T{{}};
......@@ -318,6 +326,8 @@ test "tuple type with void field" {
318326}
319327
320328test "zero sized struct in tuple handled correctly" {
329 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
330
321331 const State = struct {
322332 const Self = @This();
323333 data: @Type(.{
......@@ -347,6 +357,7 @@ test "zero sized struct in tuple handled correctly" {
347357test "tuple type with void field and a runtime field" {
348358 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
349359 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
360 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
350361
351362 const T = std.meta.Tuple(&[_]type{ usize, void });
352363 var t: T = .{ 5, {} };
......@@ -358,6 +369,7 @@ test "branching inside tuple literal" {
358369 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
359370 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
360371 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
372 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
361373
362374 const S = struct {
363375 fn foo(a: anytype) !void {
......@@ -373,6 +385,7 @@ test "tuple initialized with a runtime known value" {
373385 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
374386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
375387 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
388 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
376389
377390 const E = union(enum) { e: []const u8 };
378391 const W = union(enum) { w: E };
......@@ -387,6 +400,7 @@ test "tuple of struct concatenation and coercion to array" {
387400 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
388401 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
389402 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
403 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
390404
391405 const StructWithDefault = struct { value: f32 = 42 };
392406 const SomeStruct = struct { array: [4]StructWithDefault };
......@@ -401,6 +415,7 @@ test "nested runtime conditionals in tuple initializer" {
401415 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
402416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
403417 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
418 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
404419
405420 var data: u8 = 0;
406421 _ = &data;
......@@ -459,6 +474,7 @@ test "coerce anon tuple to tuple" {
459474 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
460475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
461476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
477 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
462478
463479 var x: u8 = 1;
464480 var y: u16 = 2;
......@@ -493,6 +509,7 @@ test "tuple with runtime value coerced into a slice with a sentinel" {
493509 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
494510 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
495511 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
512 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
496513
497514 const S = struct {
498515 fn f(a: [:null]const ?u8) !void {
......@@ -562,6 +579,8 @@ test "comptime fields in tuple can be initialized" {
562579}
563580
564581test "tuple default values" {
582 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
583
565584 const T = struct {
566585 usize,
567586 usize = 123,
test/behavior/tuple_declarations.zig+2
......@@ -7,6 +7,7 @@ const expectEqualStrings = testing.expectEqualStrings;
77test "tuple declaration type info" {
88 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1011
1112 {
1213 const T = struct { comptime u32 align(2) = 1, []const u8 };
......@@ -35,6 +36,7 @@ test "tuple declaration type info" {
3536test "Tuple declaration usage" {
3637 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3738 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
39 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3840
3941 const T = struct { u32, []const u8 };
4042 var t: T = .{ 1, "foo" };
test/behavior/type.zig+3
......@@ -203,6 +203,7 @@ test "Type.Opaque" {
203203 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
204204 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
205205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
206207
207208 const Opaque = @Type(.{
208209 .Opaque = .{
......@@ -260,6 +261,7 @@ test "Type.Struct" {
260261 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
261262 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
262263 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
264 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
263265
264266 const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
265267 const infoA = @typeInfo(A).Struct;
......@@ -383,6 +385,7 @@ test "Type.Union" {
383385 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
384386 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
385387 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
388 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
386389
387390 const Untagged = @Type(.{
388391 .Union = .{
test/behavior/type_info.zig+5
......@@ -565,6 +565,8 @@ test "StructField.is_comptime" {
565565}
566566
567567test "typeInfo resolves usingnamespace declarations" {
568 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
569
568570 const A = struct {
569571 pub const f1 = 42;
570572 };
......@@ -590,6 +592,7 @@ test "value from struct @typeInfo default_value can be loaded at comptime" {
590592test "@typeInfo decls and usingnamespace" {
591593 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
592594 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
595 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
593596
594597 const A = struct {
595598 pub const x = 5;
......@@ -630,6 +633,8 @@ test "type info of tuple of string literal default value" {
630633}
631634
632635test "@typeInfo only contains pub decls" {
636 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
637
633638 const other = struct {
634639 const std = @import("std");
635640
test/behavior/typename.zig+8
......@@ -16,6 +16,7 @@ test "anon fn param" {
1616 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1717 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1818 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1920
2021 // https://github.com/ziglang/zig/issues/9339
2122 try expectEqualStringsIgnoreDigits(
......@@ -41,6 +42,7 @@ test "anon field init" {
4142 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4344 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
45 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4446
4547 const Foo = .{
4648 .T1 = struct {},
......@@ -66,6 +68,7 @@ test "basic" {
6668 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6769 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6870 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
71 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6972
7073 try expectEqualStrings("i64", @typeName(i64));
7174 try expectEqualStrings("*usize", @typeName(*usize));
......@@ -87,6 +90,7 @@ test "top level decl" {
8790 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8891 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8992 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
93 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9094
9195 try expectEqualStrings(
9296 "behavior.typename.A_Struct",
......@@ -136,6 +140,7 @@ test "fn param" {
136140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
137141 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
139144
140145 // https://github.com/ziglang/zig/issues/675
141146 try expectEqualStrings(
......@@ -215,6 +220,7 @@ test "local variable" {
215220 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
216221 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
217222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
223 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
218224
219225 const Foo = struct { a: u32 };
220226 const Bar = union { a: u32 };
......@@ -233,6 +239,7 @@ test "comptime parameters not converted to anytype in function type" {
233239 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
234240 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
235241 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
242 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
236243
237244 const T = fn (fn (type) void, void) void;
238245 try expectEqualStrings("fn (comptime fn (comptime type) void, void) void", @typeName(T));
......@@ -242,6 +249,7 @@ test "anon name strategy used in sub expression" {
242249 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
243250 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
244251 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
245253
246254 const S = struct {
247255 fn getTheName() []const u8 {
test/behavior/undefined.zig+2
......@@ -91,6 +91,7 @@ test "reslice of undefined global var slice" {
9191 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
9292 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9393 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
94 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9495
9596 var stack_buf: [100]u8 = [_]u8{0} ** 100;
9697 buf = &stack_buf;
......@@ -103,6 +104,7 @@ test "returned undef is 0xaa bytes when runtime safety is enabled" {
103104 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
104105 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
105106 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
106108
107109 const Rect = struct {
108110 x: f32,
test/behavior/underscore.zig+1
......@@ -8,6 +8,7 @@ test "ignore lval with underscore" {
88
99test "ignore lval with underscore (while loop)" {
1010 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1112
1213 while (optionalReturnError()) |_| {
1314 while (optionalReturnError()) |_| {
test/behavior/union.zig+66
......@@ -15,6 +15,7 @@ test "basic unions with floats" {
1515 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1616 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1717 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1819
1920 var foo = FooWithFloats{ .int = 1 };
2021 try expect(foo.int == 1);
......@@ -30,6 +31,7 @@ test "init union with runtime value - floats" {
3031 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3132 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
34 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3335
3436 var foo: FooWithFloats = undefined;
3537
......@@ -41,6 +43,7 @@ test "basic unions" {
4143 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
4244 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4345 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
46 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4447
4548 var foo = Foo{ .int = 1 };
4649 try expect(foo.int == 1);
......@@ -59,6 +62,7 @@ test "init union with runtime value" {
5962 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6063 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
6164 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
65 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6266
6367 var foo: Foo = undefined;
6468
......@@ -97,6 +101,7 @@ const FooExtern = extern union {
97101test "basic extern unions" {
98102 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
99103 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
104 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
100105
101106 var foo = FooExtern{ .int = 1 };
102107 try expect(foo.int == 1);
......@@ -168,6 +173,7 @@ test "constant tagged union with payload" {
168173 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
169174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
170175 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
176 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
171177
172178 var empty = TaggedUnionWithPayload{ .Empty = {} };
173179 var full = TaggedUnionWithPayload{ .Full = 13 };
......@@ -218,6 +224,7 @@ test "union with specified enum tag" {
218224 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
219225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
220226 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
227 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
221228
222229 try doTest();
223230 try comptime doTest();
......@@ -228,6 +235,7 @@ test "packed union generates correctly aligned type" {
228235 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
229236 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
230237 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
238 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
231239
232240 const U = packed union {
233241 f1: *const fn () error{TestUnexpectedResult}!void,
......@@ -268,6 +276,7 @@ test "comparison between union and enum literal" {
268276 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
269277 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
270278 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
279 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
271280
272281 try testComparison();
273282 try comptime testComparison();
......@@ -283,6 +292,7 @@ test "cast union to tag type of union" {
283292 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
284293 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
285294 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
295 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
286296
287297 try testCastUnionToTag();
288298 try comptime testCastUnionToTag();
......@@ -304,6 +314,7 @@ test "cast tag type of union to union" {
304314 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
305315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
306316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
317 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
307318
308319 var x: Value2 = Letter2.B;
309320 _ = &x;
......@@ -320,6 +331,7 @@ test "implicit cast union to its tag type" {
320331 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
321332 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
322333 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
334 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
323335
324336 var x: Value2 = Letter2.B;
325337 _ = &x;
......@@ -341,6 +353,7 @@ test "constant packed union" {
341353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
342354 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
343355 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
356 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
344357
345358 try testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }});
346359}
......@@ -405,6 +418,7 @@ test "tagged union initialization with runtime void" {
405418 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
406419 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
407420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
421 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
408422
409423 try expect(testTaggedUnionInit({}));
410424}
......@@ -490,6 +504,7 @@ test "initialize global array of union" {
490504 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
491505 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
492506 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
493508
494509 glbl_array[1] = FooUnion{ .U1 = 2 };
495510 glbl_array[0] = FooUnion{ .U0 = 1 };
......@@ -501,6 +516,7 @@ test "update the tag value for zero-sized unions" {
501516 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
502517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
503518 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
519 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
504520
505521 const S = union(enum) {
506522 U0: void,
......@@ -605,6 +621,7 @@ test "tagged union as return value" {
605621 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
606622 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
607623 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
624 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
608625
609626 switch (returnAnInt(13)) {
610627 TaggedFoo.One => |value| try expect(value == 13),
......@@ -620,6 +637,7 @@ test "tagged union with all void fields but a meaningful tag" {
620637 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
621638 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
622639 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
640 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
623641
624642 const S = struct {
625643 const B = union(enum) {
......@@ -648,6 +666,7 @@ test "union(enum(u32)) with specified and unspecified tag values" {
648666 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
649667 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
650668 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
669 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
651670
652671 comptime assert(Tag(Tag(MultipleChoice2)) == u32);
653672 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
......@@ -740,6 +759,7 @@ test "@intFromEnum works on unions" {
740759 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
741760 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
742761 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
762 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
743763
744764 const Bar = union(enum) {
745765 A: bool,
......@@ -799,6 +819,7 @@ test "return union init with void payload" {
799819 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
800820 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
801821 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
822 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
802823
803824 const S = struct {
804825 fn entry() !void {
......@@ -823,6 +844,7 @@ test "@unionInit stored to a const" {
823844 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
824845 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
825846 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
847 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
826848
827849 const S = struct {
828850 const U = union(enum) {
......@@ -853,6 +875,7 @@ test "@unionInit can modify a union type" {
853875 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
854876 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
855877 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
878 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
856879
857880 const UnionInitEnum = union(enum) {
858881 Boolean: bool,
......@@ -876,6 +899,7 @@ test "@unionInit can modify a pointer value" {
876899 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
877900 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
878901 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
902 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
879903
880904 const UnionInitEnum = union(enum) {
881905 Boolean: bool,
......@@ -931,6 +955,7 @@ test "anonymous union literal syntax" {
931955 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
932956 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
933957 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
958 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
934959
935960 const S = struct {
936961 const Number = union {
......@@ -958,6 +983,7 @@ test "function call result coerces from tagged union to the tag" {
958983 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
959984 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
960985 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
986 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
961987
962988 const S = struct {
963989 const Arch = union(enum) {
......@@ -993,6 +1019,7 @@ test "cast from anonymous struct to union" {
9931019 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9941020 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9951021 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1022 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9961023
9971024 const S = struct {
9981025 const U = union(enum) {
......@@ -1027,6 +1054,7 @@ test "cast from pointer to anonymous struct to pointer to union" {
10271054 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10281055 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10291056 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1057 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10301058
10311059 const S = struct {
10321060 const U = union(enum) {
......@@ -1061,6 +1089,7 @@ test "switching on non exhaustive union" {
10611089 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10621090 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10631091 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1092 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10641093
10651094 const S = struct {
10661095 const E = enum(u8) {
......@@ -1120,6 +1149,7 @@ test "@unionInit on union with tag but no fields" {
11201149 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11211150 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11221151 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1152 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11231153
11241154 const S = struct {
11251155 const Type = enum(u8) { no_op = 105 };
......@@ -1169,6 +1199,7 @@ test "global variable struct contains union initialized to non-most-aligned fiel
11691199 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11701200 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11711201 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1202 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11721203
11731204 const T = struct {
11741205 const U = union(enum) {
......@@ -1195,6 +1226,7 @@ test "union with no result loc initiated with a runtime value" {
11951226 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11961227 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11971228 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1229 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11981230
11991231 const U = union {
12001232 a: u32,
......@@ -1212,6 +1244,7 @@ test "union with a large struct field" {
12121244 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12131245 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12141246 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1247 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12151248
12161249 const S = struct {
12171250 a: [8]usize,
......@@ -1246,6 +1279,7 @@ test "union tag is set when initiated as a temporary value at runtime" {
12461279 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12471280 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12481281 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1282 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12491283
12501284 const U = union(enum) {
12511285 a,
......@@ -1266,6 +1300,7 @@ test "extern union most-aligned field is smaller" {
12661300 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12671301 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12681302 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1303 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12691304
12701305 const U = extern union {
12711306 in6: extern struct {
......@@ -1285,6 +1320,7 @@ test "return an extern union from C calling convention" {
12851320 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12861321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12871322 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1323 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12881324
12891325 const namespace = struct {
12901326 const S = extern struct {
......@@ -1316,6 +1352,7 @@ test "noreturn field in union" {
13161352 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13171353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13181354 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1355 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13191356
13201357 const U = union(enum) {
13211358 a: u32,
......@@ -1367,6 +1404,7 @@ test "@unionInit uses tag value instead of field index" {
13671404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13681405 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13691406 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1407 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13701408
13711409 const E = enum(u8) {
13721410 b = 255,
......@@ -1396,6 +1434,7 @@ test "union field ptr - zero sized payload" {
13961434 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13971435 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13981436 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1437 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13991438
14001439 const U = union {
14011440 foo: void,
......@@ -1410,6 +1449,7 @@ test "union field ptr - zero sized field" {
14101449 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14111450 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14121451 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1452 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14131453
14141454 const U = union {
14151455 foo: void,
......@@ -1476,6 +1516,7 @@ test "no dependency loop when function pointer in union returns the union" {
14761516 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14771517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14781518 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1519 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14791520
14801521 const U = union(enum) {
14811522 const U = @This();
......@@ -1496,6 +1537,7 @@ test "no dependency loop when function pointer in union returns the union" {
14961537test "union reassignment can use previous value" {
14971538 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14981539 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1540 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14991541
15001542 const U = union {
15011543 a: u32,
......@@ -1547,6 +1589,7 @@ test "reinterpreting enum value inside packed union" {
15471589
15481590test "access the tag of a global tagged union" {
15491591 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1592 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15501593
15511594 const U = union(enum) {
15521595 a,
......@@ -1558,6 +1601,7 @@ test "access the tag of a global tagged union" {
15581601
15591602test "coerce enum literal to union in result loc" {
15601603 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1604 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15611605
15621606 const U = union(enum) {
15631607 a,
......@@ -1675,6 +1719,7 @@ test "packed union field pointer has correct alignment" {
16751719
16761720test "union with 128 bit integer" {
16771721 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1722 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16781723
16791724 const ValueTag = enum { int, other };
16801725
......@@ -1698,6 +1743,7 @@ test "union with 128 bit integer" {
16981743
16991744test "memset extern union" {
17001745 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1746 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17011747
17021748 const U = extern union {
17031749 foo: u8,
......@@ -1719,6 +1765,7 @@ test "memset extern union" {
17191765
17201766test "memset packed union" {
17211767 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1768 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17221769
17231770 const U = packed union {
17241771 a: u32,
......@@ -1819,6 +1866,7 @@ test "reinterpret extern union" {
18191866
18201867test "reinterpret packed union" {
18211868 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1869 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18221870
18231871 const U = packed union {
18241872 foo: u8,
......@@ -1891,6 +1939,7 @@ test "reinterpret packed union" {
18911939
18921940test "reinterpret packed union inside packed struct" {
18931941 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1942 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18941943
18951944 const U = packed union {
18961945 a: u7,
......@@ -1927,6 +1976,8 @@ test "reinterpret packed union inside packed struct" {
19271976}
19281977
19291978test "inner struct initializer uses union layout" {
1979 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1980
19301981 const namespace = struct {
19311982 const U = union {
19321983 a: struct {
......@@ -1952,6 +2003,7 @@ test "inner struct initializer uses union layout" {
19522003
19532004test "inner struct initializer uses packed union layout" {
19542005 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2006 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19552007
19562008 const namespace = struct {
19572009 const U = packed union {
......@@ -1978,6 +2030,7 @@ test "inner struct initializer uses packed union layout" {
19782030
19792031test "extern union initialized via reintepreted struct field initializer" {
19802032 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2033 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19812034
19822035 const bytes = [_]u8{ 0xaa, 0xbb, 0xcc, 0xdd };
19832036
......@@ -1997,6 +2050,7 @@ test "extern union initialized via reintepreted struct field initializer" {
19972050
19982051test "packed union initialized via reintepreted struct field initializer" {
19992052 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2053 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20002054
20012055 const bytes = [_]u8{ 0xaa, 0xbb, 0xcc, 0xdd };
20022056
......@@ -2017,6 +2071,7 @@ test "packed union initialized via reintepreted struct field initializer" {
20172071
20182072test "store of comptime reinterpreted memory to extern union" {
20192073 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2074 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20202075
20212076 const bytes = [_]u8{ 0xaa, 0xbb, 0xcc, 0xdd };
20222077
......@@ -2039,6 +2094,7 @@ test "store of comptime reinterpreted memory to extern union" {
20392094
20402095test "store of comptime reinterpreted memory to packed union" {
20412096 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2097 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20422098
20432099 const bytes = [_]u8{ 0xaa, 0xbb, 0xcc, 0xdd };
20442100
......@@ -2061,6 +2117,7 @@ test "store of comptime reinterpreted memory to packed union" {
20612117
20622118test "union field is a pointer to an aligned version of itself" {
20632119 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2120 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20642121
20652122 const E = union {
20662123 next: *align(1) @This(),
......@@ -2072,6 +2129,8 @@ test "union field is a pointer to an aligned version of itself" {
20722129}
20732130
20742131test "pass register-sized field as non-register-sized union" {
2132 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2133
20752134 const S = struct {
20762135 fn taggedUnion(u: union(enum) { x: usize, y: [2]usize }) !void {
20772136 try expectEqual(@as(usize, 42), u.x);
......@@ -2095,6 +2154,7 @@ test "pass register-sized field as non-register-sized union" {
20952154
20962155test "circular dependency through pointer field of a union" {
20972156 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2157 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20982158
20992159 const S = struct {
21002160 const UnionInner = extern struct {
......@@ -2117,6 +2177,8 @@ test "circular dependency through pointer field of a union" {
21172177}
21182178
21192179test "pass nested union with rls" {
2180 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2181
21202182 const Union = union(enum) {
21212183 a: u32,
21222184 b: union(enum) {
......@@ -2139,6 +2201,7 @@ test "runtime union init, most-aligned field != largest" {
21392201 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21402202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
21412203 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2204 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21422205
21432206 const U = union(enum) {
21442207 x: u128,
......@@ -2163,6 +2226,7 @@ test "copied union field doesn't alias source" {
21632226 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21642227 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21652228 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2229 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21662230
21672231 const U = union(enum) {
21682232 array: [10]u32,
......@@ -2183,6 +2247,7 @@ test "create union(enum) from other union(enum)" {
21832247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21842248 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21852249 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2250 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21862251
21872252 const string = "hello world";
21882253 const TempRef = struct {
......@@ -2308,6 +2373,7 @@ test "signed enum tag with negative value" {
23082373 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
23092374 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23102375 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
2376 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23112377
23122378 const Enum = enum(i8) {
23132379 a = -1,
test/behavior/union_with_members.zig+1
......@@ -21,6 +21,7 @@ test "enum with members" {
2121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2323 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
24 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2425
2526 const a = ET{ .SINT = -42 };
2627 const b = ET{ .UINT = 42 };
test/behavior/usingnamespace.zig+13
......@@ -11,6 +11,8 @@ const C = struct {
1111};
1212
1313test "basic usingnamespace" {
14 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15
1416 try std.testing.expect(C.B == bool);
1517}
1618
......@@ -21,6 +23,8 @@ fn Foo(comptime T: type) type {
2123}
2224
2325test "usingnamespace inside a generic struct" {
26 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
27
2428 const std2 = Foo(std);
2529 const testing2 = Foo(std.testing);
2630 try std2.testing.expect(true);
......@@ -32,6 +36,8 @@ usingnamespace struct {
3236};
3337
3438test "usingnamespace does not redeclare an imported variable" {
39 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
40
3541 try comptime std.testing.expect(@This().foo == 42);
3642}
3743
......@@ -39,6 +45,7 @@ usingnamespace @import("usingnamespace/foo.zig");
3945test "usingnamespace omits mixing in private functions" {
4046 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
4147 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4249
4350 try expect(@This().privateFunction());
4451 try expect(!@This().printText());
......@@ -48,6 +55,8 @@ fn privateFunction() bool {
4855}
4956
5057test {
58 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
59
5160 _ = @import("usingnamespace/import_segregation.zig");
5261}
5362
......@@ -55,6 +64,7 @@ usingnamespace @import("usingnamespace/a.zig");
5564test "two files usingnamespace import each other" {
5665 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
5766 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
67 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5868
5969 try expect(@This().ok());
6070}
......@@ -62,6 +72,7 @@ test "two files usingnamespace import each other" {
6272test {
6373 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6474 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
75 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6576
6677 const AA = struct {
6778 x: i32,
......@@ -94,6 +105,8 @@ const Mixin = struct {
94105};
95106
96107test "container member access usingnamespace decls" {
108 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
109
97110 var foo = Bar{};
98111 foo.two();
99112}
test/behavior/usingnamespace/file_1.zig+3
......@@ -1,9 +1,12 @@
11const std = @import("std");
22const expect = std.testing.expect;
33const imports = @import("imports.zig");
4const builtin = @import("builtin");
45
56const A = 456;
67
78test {
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10
811 try expect(imports.A == 123);
912}
test/behavior/usingnamespace/import_segregation.zig+1
......@@ -6,6 +6,7 @@ usingnamespace @import("bar.zig");
66
77test "no clobbering happened" {
88 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910
1011 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
1112 // https://github.com/ziglang/zig/issues/16846
test/behavior/var_args.zig+15
......@@ -14,6 +14,8 @@ fn add(args: anytype) i32 {
1414}
1515
1616test "add arbitrary args" {
17 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18
1719 try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
1820 try expect(add(.{@as(i32, 1234)}) == 1234);
1921 try expect(add(.{}) == 0);
......@@ -24,12 +26,15 @@ fn readFirstVarArg(args: anytype) void {
2426}
2527
2628test "send void arg to var args" {
29 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
30
2731 readFirstVarArg(.{{}});
2832}
2933
3034test "pass args directly" {
3135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3236 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3338
3439 try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
3540 try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);
......@@ -43,6 +48,7 @@ fn addSomeStuff(args: anytype) i32 {
4348test "runtime parameter before var args" {
4449 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4550 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4652
4753 try expect((try extraFn(10, .{})) == 0);
4854 try expect((try extraFn(10, .{false})) == 1);
......@@ -81,11 +87,15 @@ fn foo2(args: anytype) bool {
8187}
8288
8389test "array of var args functions" {
90 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
91
8492 try expect(foos[0](.{}));
8593 try expect(!foos[1](.{}));
8694}
8795
8896test "pass zero length array to var args param" {
97 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
98
8999 doNothingWithFirstArg(.{""});
90100}
91101
......@@ -99,6 +109,7 @@ test "simple variadic function" {
99109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
100110 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
101111 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
102113 if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) {
103114 // https://github.com/ziglang/zig/issues/14096
104115 return error.SkipZigTest;
......@@ -158,6 +169,7 @@ test "coerce reference to var arg" {
158169 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
159170 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
160171 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
172 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
161173 if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) {
162174 // https://github.com/ziglang/zig/issues/14096
163175 return error.SkipZigTest;
......@@ -189,6 +201,7 @@ test "variadic functions" {
189201 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
190202 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
191203 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
204 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
192205 if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) {
193206 // https://github.com/ziglang/zig/issues/14096
194207 return error.SkipZigTest;
......@@ -232,6 +245,7 @@ test "copy VaList" {
232245 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
233246 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
234247 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
248 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
235249 if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) {
236250 // https://github.com/ziglang/zig/issues/14096
237251 return error.SkipZigTest;
......@@ -264,6 +278,7 @@ test "unused VaList arg" {
264278 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
265279 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
266280 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
281 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
267282 if (builtin.os.tag != .macos and comptime builtin.cpu.arch.isAARCH64()) {
268283 // https://github.com/ziglang/zig/issues/14096
269284 return error.SkipZigTest;
test/behavior/vector.zig+45-1
......@@ -28,6 +28,7 @@ test "vector wrap operators" {
2828 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2929 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
3030 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
31 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3132 if (builtin.zig_backend == .stage2_x86_64 and
3233 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
3334
......@@ -52,6 +53,7 @@ test "vector bin compares with mem.eql" {
5253 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
5354 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5455 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5557
5658 const S = struct {
5759 fn doTheTest() !void {
......@@ -76,6 +78,7 @@ test "vector int operators" {
7678 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7779 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7880 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7982
8083 const S = struct {
8184 fn doTheTest() !void {
......@@ -100,6 +103,7 @@ test "vector float operators" {
100103 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
101104 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
102105 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
106 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
103107
104108 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
105109 const S = struct {
......@@ -123,6 +127,7 @@ test "vector bit operators" {
123127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
124128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
125129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
130 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
126131
127132 const S = struct {
128133 fn doTheTest() !void {
......@@ -142,6 +147,7 @@ test "implicit cast vector to array" {
142147 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
143148 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
144149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
150 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
145151
146152 const S = struct {
147153 fn doTheTest() !void {
......@@ -160,6 +166,7 @@ test "array to vector" {
160166 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
161167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
162168 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
169 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
163170
164171 const S = struct {
165172 fn doTheTest() !void {
......@@ -180,6 +187,7 @@ test "array vector coercion - odd sizes" {
180187 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
181188 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
182189 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
190 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
183191
184192 const S = struct {
185193 fn doTheTest() !void {
......@@ -219,6 +227,7 @@ test "array to vector with element type coercion" {
219227 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
220228 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
221229 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
230 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
222231
223232 const S = struct {
224233 fn doTheTest() !void {
......@@ -258,6 +267,7 @@ test "tuple to vector" {
258267 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
259268 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
260269 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
270 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
261271
262272 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
263273 // Regressed with LLVM 14:
......@@ -287,6 +297,7 @@ test "vector casts of sizes not divisible by 8" {
287297 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
288298 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
289299 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
300 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
290301
291302 const S = struct {
292303 fn doTheTest() !void {
......@@ -325,6 +336,7 @@ test "vector @splat" {
325336 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
326337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
327338 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
328340
329341 if (builtin.zig_backend == .stage2_llvm and
330342 builtin.os.tag == .macos)
......@@ -371,6 +383,7 @@ test "load vector elements via comptime index" {
371383 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
372384 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
373385 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
386 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
374387
375388 const S = struct {
376389 fn doTheTest() !void {
......@@ -392,6 +405,7 @@ test "store vector elements via comptime index" {
392405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
393406 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
394407 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
408 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
395409
396410 const S = struct {
397411 fn doTheTest() !void {
......@@ -441,6 +455,7 @@ test "store vector elements via runtime index" {
441455 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
442456 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
443457 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
458 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
444459
445460 const S = struct {
446461 fn doTheTest() !void {
......@@ -485,6 +500,7 @@ test "vector comparison operators" {
485500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
486501 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
487502 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
503 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
488504
489505 const S = struct {
490506 fn doTheTest() !void {
......@@ -532,6 +548,7 @@ test "vector division operators" {
532548 if (builtin.zig_backend == .stage2_llvm and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
533549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
534550 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
551 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
535552
536553 const S = struct {
537554 fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {
......@@ -622,6 +639,7 @@ test "vector bitwise not operator" {
622639 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
623640 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
624641 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
642 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
625643
626644 const S = struct {
627645 fn doTheTestNot(comptime T: type, x: @Vector(4, T)) !void {
......@@ -653,6 +671,7 @@ test "vector shift operators" {
653671 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
654672 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
655673 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
674 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
656675
657676 const S = struct {
658677 fn doTheTestShift(x: anytype, y: anytype) !void {
......@@ -743,6 +762,7 @@ test "vector reduce operation" {
743762 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
744763 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
745764 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
765 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
746766
747767 const S = struct {
748768 fn testReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {
......@@ -901,6 +921,7 @@ test "mask parameter of @shuffle is comptime scope" {
901921 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
902922 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
903923 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
924 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
904925 if (builtin.zig_backend == .stage2_x86_64 and
905926 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .ssse3)) return error.SkipZigTest;
906927
......@@ -927,6 +948,7 @@ test "saturating add" {
927948 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
928949 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
929950 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
951 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
930952
931953 const S = struct {
932954 fn doTheTest() !void {
......@@ -961,6 +983,7 @@ test "saturating subtraction" {
961983 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
962984 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
963985 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
986 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
964987
965988 const S = struct {
966989 fn doTheTest() !void {
......@@ -985,6 +1008,7 @@ test "saturating multiplication" {
9851008 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9861009 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9871010 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1011 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9881012
9891013 // TODO: once #9660 has been solved, remove this line
9901014 if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest;
......@@ -1013,6 +1037,7 @@ test "saturating shift-left" {
10131037 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10141038 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10151039 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1040 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10161041
10171042 const S = struct {
10181043 fn doTheTest() !void {
......@@ -1036,6 +1061,7 @@ test "multiplication-assignment operator with an array operand" {
10361061 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10371062 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10381063 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1064 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10391065
10401066 const S = struct {
10411067 fn doTheTest() !void {
......@@ -1056,6 +1082,7 @@ test "@addWithOverflow" {
10561082 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10571083 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10581084 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1085 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10591086
10601087 const S = struct {
10611088 fn doTheTest() !void {
......@@ -1103,6 +1130,7 @@ test "@subWithOverflow" {
11031130 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11041131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11051132 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1133 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11061134
11071135 const S = struct {
11081136 fn doTheTest() !void {
......@@ -1134,6 +1162,7 @@ test "@mulWithOverflow" {
11341162 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11351163 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11361164 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1165 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11371166
11381167 const S = struct {
11391168 fn doTheTest() !void {
......@@ -1155,6 +1184,7 @@ test "@shlWithOverflow" {
11551184 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11561185 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11571186 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1187 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11581188
11591189 const S = struct {
11601190 fn doTheTest() !void {
......@@ -1198,6 +1228,7 @@ test "loading the second vector from a slice of vectors" {
11981228 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11991229 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12001230 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1231 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12011232
12021233 @setRuntimeSafety(false);
12031234 var small_bases = [2]@Vector(2, u8){
......@@ -1214,6 +1245,7 @@ test "array of vectors is copied" {
12141245 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12151246 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12161247 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1248 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12171249
12181250 const Vec3 = @Vector(3, i32);
12191251 var points = [_]Vec3{
......@@ -1237,6 +1269,7 @@ test "byte vector initialized in inline function" {
12371269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12381270 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12391271 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1272 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12401273
12411274 if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and
12421275 builtin.cpu.features.isEnabled(@intFromEnum(std.Target.x86.Feature.avx512f)))
......@@ -1306,6 +1339,7 @@ test "@intCast to u0" {
13061339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13071340 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13081341 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1342 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13091343
13101344 var zeros = @Vector(2, u32){ 0, 0 };
13111345 _ = &zeros;
......@@ -1330,6 +1364,7 @@ test "array operands to shuffle are coerced to vectors" {
13301364 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13311365 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13321366 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1367 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13331368
13341369 const mask = [5]i32{ -1, 0, 1, 2, 3 };
13351370
......@@ -1345,6 +1380,7 @@ test "load packed vector element" {
13451380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13461381 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13471382 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1383 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13481384
13491385 var x: @Vector(2, u15) = .{ 1, 4 };
13501386 try expect((&x[0]).* == 1);
......@@ -1358,6 +1394,7 @@ test "store packed vector element" {
13581394 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13591395 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13601396 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1397 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13611398
13621399 var v = @Vector(4, u1){ 1, 1, 1, 1 };
13631400 try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v);
......@@ -1373,6 +1410,7 @@ test "store to vector in slice" {
13731410 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13741411 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13751412 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1413 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13761414
13771415 var v = [_]@Vector(3, f32){
13781416 .{ 1, 1, 1 },
......@@ -1392,6 +1430,8 @@ test "store vector with memset" {
13921430 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13931431 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13941432 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
1433 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1434 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13951435
13961436 if (builtin.zig_backend == .stage2_llvm) {
13971437 switch (builtin.target.cpu.arch) {
......@@ -1437,6 +1477,7 @@ test "store vector with memset" {
14371477test "addition of vectors represented as strings" {
14381478 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14391479 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1480 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14401481
14411482 const V = @Vector(3, u8);
14421483 const foo: V = "foo".*;
......@@ -1450,6 +1491,7 @@ test "compare vectors with different element types" {
14501491 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
14511492 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
14521493 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1494 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14531495
14541496 var a: @Vector(2, u8) = .{ 1, 2 };
14551497 var b: @Vector(2, u9) = .{ 3, 0 };
......@@ -1462,6 +1504,7 @@ test "vector pointer is indexable" {
14621504 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14631505 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
14641506 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1507 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14651508
14661509 const V = @Vector(2, u32);
14671510
......@@ -1502,6 +1545,7 @@ test "bitcast to vector with different child type" {
15021545 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15031546 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
15041547 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1548 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15051549
15061550 const S = struct {
15071551 fn doTheTest() !void {
......@@ -1530,7 +1574,6 @@ test "arithmetic on zero-length vectors" {
15301574 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
15311575 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15321576 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1533 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
15341577 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15351578
15361579 {
......@@ -1565,6 +1608,7 @@ test "@reduce on bool vector" {
15651608test "bitcast vector to array of smaller vectors" {
15661609 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15671610 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1611 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15681612
15691613 const u8x32 = @Vector(32, u8);
15701614 const u8x64 = @Vector(64, u8);
test/behavior/void.zig+2
......@@ -20,6 +20,7 @@ test "compare void with void compile time known" {
2020
2121test "iterate over a void slice" {
2222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2324
2425 var j: usize = 0;
2526 for (times(10), 0..) |_, i| {
......@@ -36,6 +37,7 @@ test "void optional" {
3637 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3738 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3839 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
40 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3941
4042 var x: ?void = {};
4143 _ = &x;
test/behavior/wasm.zig+2
......@@ -3,6 +3,8 @@ const expect = std.testing.expect;
33const builtin = @import("builtin");
44
55test "memory size and grow" {
6 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7
68 var prev = @wasmMemorySize(0);
79 _ = &prev;
810 try expect(prev == @wasmMemoryGrow(0, 1));
test/behavior/while.zig+13
......@@ -106,6 +106,7 @@ fn testBreakOuter() void {
106106test "while copies its payload" {
107107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
108108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
109110
110111 const S = struct {
111112 fn doTheTest() !void {
......@@ -144,6 +145,7 @@ fn runContinueAndBreakTest() !void {
144145test "while with optional as condition" {
145146 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
146147 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
148 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
147149
148150 numbers_left = 10;
149151 var sum: i32 = 0;
......@@ -156,6 +158,7 @@ test "while with optional as condition" {
156158test "while with optional as condition with else" {
157159 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
158160 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
161 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
159162
160163 numbers_left = 10;
161164 var sum: i32 = 0;
......@@ -172,6 +175,7 @@ test "while with optional as condition with else" {
172175
173176test "while with error union condition" {
174177 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
178 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
175179
176180 numbers_left = 10;
177181 var sum: i32 = 0;
......@@ -204,6 +208,7 @@ test "while on optional with else result follow else prong" {
204208 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
205209 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
206210 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
211 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
207212
208213 const result = while (returnNull()) |value| {
209214 break value;
......@@ -215,6 +220,7 @@ test "while on optional with else result follow break prong" {
215220 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
216221 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
217222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
223 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
218224
219225 const result = while (returnOptional(10)) |value| {
220226 break value;
......@@ -252,6 +258,7 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {
252258
253259test "while on error union with else result follow else prong" {
254260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
261 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
255262
256263 const result = while (returnError()) |value| {
257264 break value;
......@@ -261,6 +268,7 @@ test "while on error union with else result follow else prong" {
261268
262269test "while on error union with else result follow break prong" {
263270 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
271 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
264272
265273 const result = while (returnSuccess(10)) |value| {
266274 break value;
......@@ -287,6 +295,7 @@ test "while optional 2 break statements and an else" {
287295 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
288296 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
289297 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
298 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
290299
291300 const S = struct {
292301 fn entry(opt_t: ?bool, f: bool) !void {
......@@ -306,6 +315,7 @@ test "while error 2 break statements and an else" {
306315 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
307316 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
308317 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
318 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
309319
310320 const S = struct {
311321 fn entry(opt_t: anyerror!bool, f: bool) !void {
......@@ -344,6 +354,7 @@ test "try terminating an infinite loop" {
344354 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
345355 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
346356 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
357 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
347358
348359 // Test coverage for https://github.com/ziglang/zig/issues/13546
349360 const Foo = struct {
......@@ -371,6 +382,7 @@ test "while loop with comptime true condition needs no else block to return valu
371382test "int returned from switch in while" {
372383 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
373384 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
385 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
374386
375387 var x: u32 = 3;
376388 const val: usize = while (true) switch (x) {
......@@ -384,6 +396,7 @@ test "breaking from a loop in an if statement" {
384396 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
385397 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
386398 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
387400
388401 const S = struct {
389402 fn retOpt() ?u32 {
test/behavior/widening.zig+5
......@@ -8,6 +8,7 @@ test "integer widening" {
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
99 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1010 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1112
1213 var a: u8 = 250;
1314 var b: u16 = a;
......@@ -31,6 +32,7 @@ test "implicit unsigned integer to signed integer" {
3132 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
3334 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
35 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
3436
3537 var a: u8 = 250;
3638 var b: i16 = a;
......@@ -44,6 +46,7 @@ test "float widening" {
4446 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4547 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
4648 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
49 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4750
4851 var a: f16 = 12.34;
4952 var b: f32 = a;
......@@ -64,6 +67,7 @@ test "float widening f16 to f128" {
6467 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
6568 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6669 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
70 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
6771
6872 var x: f16 = 12.34;
6973 var y: f128 = x;
......@@ -76,6 +80,7 @@ test "cast small unsigned to larger signed" {
7680 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7781 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7882 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
83 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7984
8085 try expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200));
8186 try expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999));
test/behavior/wrapping_arithmetic.zig+3
......@@ -6,6 +6,7 @@ const expect = std.testing.expect;
66
77test "wrapping add" {
88 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
910
1011 const S = struct {
1112 fn doTheTest() !void {
......@@ -43,6 +44,7 @@ test "wrapping add" {
4344
4445test "wrapping subtraction" {
4546 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
47 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
4648
4749 const S = struct {
4850 fn doTheTest() !void {
......@@ -78,6 +80,7 @@ test "wrapping subtraction" {
7880
7981test "wrapping multiplication" {
8082 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
83 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8184
8285 // TODO: once #9660 has been solved, remove this line
8386 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest;
test/cases/compile_errors/capture_by_ref_while.zig+1-1
......@@ -7,4 +7,4 @@ test {
77// target=native
88//
99// :2:25: error: unused capture
10// :2:39: error: unused capture
\ No newline at end of file
10// :2:39: error: unused capture
test/cases/compile_errors/switch_expression-missing_error_prong.zig+1-1
......@@ -1,4 +1,4 @@
1const Error = error {
1const Error = error{
22 One,
33 Two,
44 Three,
test/cases/compile_errors/switch_expression-multiple_else_prongs.zig+2-2
......@@ -5,14 +5,14 @@ fn f(x: u32) void {
55 else => true,
66 };
77}
8fn g(x: error{Foo, Bar, Baz}!u32) void {
8fn g(x: error{ Foo, Bar, Baz }!u32) void {
99 const value: bool = if (x) |_| true else |e| switch (e) {
1010 error.Foo => false,
1111 else => true,
1212 else => true,
1313 };
1414}
15fn h(x: error{Foo, Bar, Baz}!u32) void {
15fn h(x: error{ Foo, Bar, Baz }!u32) void {
1616 const value: u32 = x catch |e| switch (e) {
1717 error.Foo => 1,
1818 else => 2,
test/cases/inherit_want_safety.zig+1-1
......@@ -28,7 +28,7 @@ pub export fn entry() usize {
2828 } else |e| switch (e) {
2929 else => {
3030 u += 1;
31 }
31 },
3232 }
3333 return u;
3434}
test/tests.zig+14
......@@ -435,6 +435,16 @@ const test_targets = blk: {
435435 // .use_llvm = true,
436436 //},
437437
438 .{
439 .target = .{
440 .cpu_arch = .riscv64,
441 .os_tag = .linux,
442 .abi = .musl,
443 },
444 .use_llvm = false,
445 .use_lld = false,
446 },
447
438448 // https://github.com/ziglang/zig/issues/3340
439449 //.{
440450 // .target = .{
......@@ -1019,6 +1029,10 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10191029 test_target.use_llvm == false and mem.eql(u8, options.name, "std"))
10201030 continue;
10211031
1032 if (target.cpu.arch != .x86_64 and
1033 test_target.use_llvm == false and mem.eql(u8, options.name, "c-import"))
1034 continue;
1035
10221036 if (target.cpu.arch == .x86_64 and target.os.tag == .windows and
10231037 test_target.target.cpu_arch == null and test_target.optimize_mode != .Debug and
10241038 mem.eql(u8, options.name, "std"))