| author | |
| committer | |
| log | 0f1652dc603ad43be733cfdd721cedf38d9e45d9 |
| tree | 48d5f6a90d1b2435eda1fa6eb66ba4b620536d36 |
| parent | 62a0fbdaef575c857a7fa5f911447dd7275c9f22 |
| parent | da335f0ee4dfe5a736919acc5ab20777838b42c7 |
| signature |
x86_64: support operations that are implemented in compiler_rt20 files changed, 1894 insertions(+), 1358 deletions(-)
lib/compiler_rt/common.zig+2-2| ... | @@ -82,7 +82,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ? | ... | @@ -82,7 +82,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ? |
| 82 | /// need for extending them to wider fp types. | 82 | /// need for extending them to wider fp types. |
| 83 | /// TODO remove this; do this type selection in the language rather than | 83 | /// TODO remove this; do this type selection in the language rather than |
| 84 | /// here in compiler-rt. | 84 | /// here in compiler-rt. |
| 85 | pub fn F16T(comptime other_type: type) type { | 85 | pub fn F16T(comptime OtherType: type) type { |
| 86 | return switch (builtin.cpu.arch) { | 86 | return switch (builtin.cpu.arch) { |
| 87 | .arm, .armeb, .thumb, .thumbeb => if (std.Target.arm.featureSetHas(builtin.cpu.features, .has_v8)) | 87 | .arm, .armeb, .thumb, .thumbeb => if (std.Target.arm.featureSetHas(builtin.cpu.features, .has_v8)) |
| 88 | switch (builtin.abi.floatAbi()) { | 88 | switch (builtin.abi.floatAbi()) { |
| ... | @@ -93,7 +93,7 @@ pub fn F16T(comptime other_type: type) type { | ... | @@ -93,7 +93,7 @@ pub fn F16T(comptime other_type: type) type { |
| 93 | u16, | 93 | u16, |
| 94 | .aarch64, .aarch64_be, .aarch64_32 => f16, | 94 | .aarch64, .aarch64_be, .aarch64_32 => f16, |
| 95 | .riscv64 => if (builtin.zig_backend == .stage1) u16 else f16, | 95 | .riscv64 => if (builtin.zig_backend == .stage1) u16 else f16, |
| 96 | .x86, .x86_64 => if (builtin.target.isDarwin()) switch (other_type) { | 96 | .x86, .x86_64 => if (builtin.target.isDarwin()) switch (OtherType) { |
| 97 | // Starting with LLVM 16, Darwin uses different abi for f16 | 97 | // Starting with LLVM 16, Darwin uses different abi for f16 |
| 98 | // depending on the type of the other return/argument..??? | 98 | // depending on the type of the other return/argument..??? |
| 99 | f32, f64 => u16, | 99 | f32, f64 => u16, |
src/Compilation.zig+1-2| ... | @@ -1871,8 +1871,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1871,8 +1871,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1871 | comp.job_queued_compiler_rt_lib = true; | 1871 | comp.job_queued_compiler_rt_lib = true; |
| 1872 | } else if (options.output_mode != .Obj) { | 1872 | } else if (options.output_mode != .Obj) { |
| 1873 | log.debug("queuing a job to build compiler_rt_obj", .{}); | 1873 | log.debug("queuing a job to build compiler_rt_obj", .{}); |
| 1874 | // If build-obj with -fcompiler-rt is requested, that is handled specially | 1874 | // In this case we are making a static library, so we ask |
| 1875 | // elsewhere. In this case we are making a static library, so we ask | ||
| 1876 | // for a compiler-rt object to put in it. | 1875 | // for a compiler-rt object to put in it. |
| 1877 | comp.job_queued_compiler_rt_obj = true; | 1876 | comp.job_queued_compiler_rt_obj = true; |
| 1878 | } | 1877 | } |
src/InternPool.zig+10-15| ... | @@ -5407,19 +5407,19 @@ pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeIni | ... | @@ -5407,19 +5407,19 @@ pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeIni |
| 5407 | 5407 | ||
| 5408 | /// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`. | 5408 | /// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`. |
| 5409 | pub const GetFuncTypeKey = struct { | 5409 | pub const GetFuncTypeKey = struct { |
| 5410 | param_types: []Index, | 5410 | param_types: []const Index, |
| 5411 | return_type: Index, | 5411 | return_type: Index, |
| 5412 | comptime_bits: u32, | 5412 | comptime_bits: u32 = 0, |
| 5413 | noalias_bits: u32, | 5413 | noalias_bits: u32 = 0, |
| 5414 | /// `null` means generic. | 5414 | /// `null` means generic. |
| 5415 | alignment: ?Alignment, | 5415 | alignment: ?Alignment = .none, |
| 5416 | /// `null` means generic. | 5416 | /// `null` means generic. |
| 5417 | cc: ?std.builtin.CallingConvention, | 5417 | cc: ?std.builtin.CallingConvention = .Unspecified, |
| 5418 | is_var_args: bool, | 5418 | is_var_args: bool = false, |
| 5419 | is_generic: bool, | 5419 | is_generic: bool = false, |
| 5420 | is_noinline: bool, | 5420 | is_noinline: bool = false, |
| 5421 | section_is_generic: bool, | 5421 | section_is_generic: bool = false, |
| 5422 | addrspace_is_generic: bool, | 5422 | addrspace_is_generic: bool = false, |
| 5423 | }; | 5423 | }; |
| 5424 | 5424 | ||
| 5425 | pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index { | 5425 | pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index { |
| ... | @@ -5754,15 +5754,10 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) | ... | @@ -5754,15 +5754,10 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) |
| 5754 | const func_ty = try ip.getFuncType(gpa, .{ | 5754 | const func_ty = try ip.getFuncType(gpa, .{ |
| 5755 | .param_types = arg.param_types, | 5755 | .param_types = arg.param_types, |
| 5756 | .return_type = arg.bare_return_type, | 5756 | .return_type = arg.bare_return_type, |
| 5757 | .comptime_bits = 0, | ||
| 5758 | .noalias_bits = arg.noalias_bits, | 5757 | .noalias_bits = arg.noalias_bits, |
| 5759 | .alignment = arg.alignment, | 5758 | .alignment = arg.alignment, |
| 5760 | .cc = arg.cc, | 5759 | .cc = arg.cc, |
| 5761 | .is_var_args = false, | ||
| 5762 | .is_generic = false, | ||
| 5763 | .is_noinline = arg.is_noinline, | 5760 | .is_noinline = arg.is_noinline, |
| 5764 | .section_is_generic = false, | ||
| 5765 | .addrspace_is_generic = false, | ||
| 5766 | }); | 5761 | }); |
| 5767 | 5762 | ||
| 5768 | const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner); | 5763 | const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner); |
src/Sema.zig+3-8| ... | @@ -7373,10 +7373,10 @@ fn analyzeCall( | ... | @@ -7373,10 +7373,10 @@ fn analyzeCall( |
| 7373 | const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); | 7373 | const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| 7374 | 7374 | ||
| 7375 | const owner_info = mod.typeToFunc(fn_owner_decl.ty).?; | 7375 | const owner_info = mod.typeToFunc(fn_owner_decl.ty).?; |
| 7376 | const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len); | ||
| 7376 | var new_fn_info: InternPool.GetFuncTypeKey = .{ | 7377 | var new_fn_info: InternPool.GetFuncTypeKey = .{ |
| 7377 | .param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len), | 7378 | .param_types = new_param_types, |
| 7378 | .return_type = owner_info.return_type, | 7379 | .return_type = owner_info.return_type, |
| 7379 | .comptime_bits = 0, | ||
| 7380 | .noalias_bits = owner_info.noalias_bits, | 7380 | .noalias_bits = owner_info.noalias_bits, |
| 7381 | .alignment = if (owner_info.align_is_generic) null else owner_info.alignment, | 7381 | .alignment = if (owner_info.align_is_generic) null else owner_info.alignment, |
| 7382 | .cc = if (owner_info.cc_is_generic) null else owner_info.cc, | 7382 | .cc = if (owner_info.cc_is_generic) null else owner_info.cc, |
| ... | @@ -7403,7 +7403,7 @@ fn analyzeCall( | ... | @@ -7403,7 +7403,7 @@ fn analyzeCall( |
| 7403 | block, | 7403 | block, |
| 7404 | &child_block, | 7404 | &child_block, |
| 7405 | inst, | 7405 | inst, |
| 7406 | new_fn_info.param_types, | 7406 | new_param_types, |
| 7407 | &arg_i, | 7407 | &arg_i, |
| 7408 | args_info, | 7408 | args_info, |
| 7409 | is_comptime_call, | 7409 | is_comptime_call, |
| ... | @@ -21144,16 +21144,11 @@ fn zirReify( | ... | @@ -21144,16 +21144,11 @@ fn zirReify( |
| 21144 | 21144 | ||
| 21145 | const ty = try mod.funcType(.{ | 21145 | const ty = try mod.funcType(.{ |
| 21146 | .param_types = param_types, | 21146 | .param_types = param_types, |
| 21147 | .comptime_bits = 0, | ||
| 21148 | .noalias_bits = noalias_bits, | 21147 | .noalias_bits = noalias_bits, |
| 21149 | .return_type = return_type.toIntern(), | 21148 | .return_type = return_type.toIntern(), |
| 21150 | .alignment = alignment, | 21149 | .alignment = alignment, |
| 21151 | .cc = cc, | 21150 | .cc = cc, |
| 21152 | .is_var_args = is_var_args, | 21151 | .is_var_args = is_var_args, |
| 21153 | .is_generic = false, | ||
| 21154 | .is_noinline = false, | ||
| 21155 | .section_is_generic = false, | ||
| 21156 | .addrspace_is_generic = false, | ||
| 21157 | }); | 21152 | }); |
| 21158 | return Air.internedToRef(ty.toIntern()); | 21153 | return Air.internedToRef(ty.toIntern()); |
| 21159 | }, | 21154 | }, |
src/arch/x86_64/CodeGen.zig+937-552| ... | @@ -215,6 +215,7 @@ pub const MCValue = union(enum) { | ... | @@ -215,6 +215,7 @@ pub const MCValue = union(enum) { |
| 215 | /// but it has not been spilled there yet in the current control flow. | 215 | /// but it has not been spilled there yet in the current control flow. |
| 216 | /// Payload is a frame index. | 216 | /// Payload is a frame index. |
| 217 | reserved_frame: FrameIndex, | 217 | reserved_frame: FrameIndex, |
| 218 | air_ref: Air.Inst.Ref, | ||
| 218 | 219 | ||
| 219 | fn isMemory(mcv: MCValue) bool { | 220 | fn isMemory(mcv: MCValue) bool { |
| 220 | return switch (mcv) { | 221 | return switch (mcv) { |
| ... | @@ -278,6 +279,7 @@ pub const MCValue = union(enum) { | ... | @@ -278,6 +279,7 @@ pub const MCValue = union(enum) { |
| 278 | .lea_tlv, | 279 | .lea_tlv, |
| 279 | .lea_frame, | 280 | .lea_frame, |
| 280 | .reserved_frame, | 281 | .reserved_frame, |
| 282 | .air_ref, | ||
| 281 | => unreachable, // not in memory | 283 | => unreachable, // not in memory |
| 282 | .memory => |addr| .{ .immediate = addr }, | 284 | .memory => |addr| .{ .immediate = addr }, |
| 283 | .indirect => |reg_off| switch (reg_off.off) { | 285 | .indirect => |reg_off| switch (reg_off.off) { |
| ... | @@ -306,6 +308,7 @@ pub const MCValue = union(enum) { | ... | @@ -306,6 +308,7 @@ pub const MCValue = union(enum) { |
| 306 | .load_tlv, | 308 | .load_tlv, |
| 307 | .load_frame, | 309 | .load_frame, |
| 308 | .reserved_frame, | 310 | .reserved_frame, |
| 311 | .air_ref, | ||
| 309 | => unreachable, // not dereferenceable | 312 | => unreachable, // not dereferenceable |
| 310 | .immediate => |addr| .{ .memory = addr }, | 313 | .immediate => |addr| .{ .memory = addr }, |
| 311 | .register => |reg| .{ .indirect = .{ .reg = reg } }, | 314 | .register => |reg| .{ .indirect = .{ .reg = reg } }, |
| ... | @@ -335,6 +338,7 @@ pub const MCValue = union(enum) { | ... | @@ -335,6 +338,7 @@ pub const MCValue = union(enum) { |
| 335 | .lea_tlv, | 338 | .lea_tlv, |
| 336 | .load_frame, | 339 | .load_frame, |
| 337 | .reserved_frame, | 340 | .reserved_frame, |
| 341 | .air_ref, | ||
| 338 | => unreachable, // not offsettable | 342 | => unreachable, // not offsettable |
| 339 | .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) }, | 343 | .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) }, |
| 340 | .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } }, | 344 | .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } }, |
| ... | @@ -366,6 +370,7 @@ pub const MCValue = union(enum) { | ... | @@ -366,6 +370,7 @@ pub const MCValue = union(enum) { |
| 366 | .lea_tlv, | 370 | .lea_tlv, |
| 367 | .lea_frame, | 371 | .lea_frame, |
| 368 | .reserved_frame, | 372 | .reserved_frame, |
| 373 | .air_ref, | ||
| 369 | => unreachable, | 374 | => unreachable, |
| 370 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| | 375 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| |
| 371 | Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr }) | 376 | Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr }) |
| ... | @@ -405,6 +410,7 @@ pub const MCValue = union(enum) { | ... | @@ -405,6 +410,7 @@ pub const MCValue = union(enum) { |
| 405 | .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), | 410 | .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), |
| 406 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), | 411 | .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), |
| 407 | .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), | 412 | .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), |
| 413 | .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), | ||
| 408 | } | 414 | } |
| 409 | } | 415 | } |
| 410 | }; | 416 | }; |
| ... | @@ -433,6 +439,7 @@ const InstTracking = struct { | ... | @@ -433,6 +439,7 @@ const InstTracking = struct { |
| 433 | => result, | 439 | => result, |
| 434 | .dead, | 440 | .dead, |
| 435 | .reserved_frame, | 441 | .reserved_frame, |
| 442 | .air_ref, | ||
| 436 | => unreachable, | 443 | => unreachable, |
| 437 | .eflags, | 444 | .eflags, |
| 438 | .register, | 445 | .register, |
| ... | @@ -491,6 +498,7 @@ const InstTracking = struct { | ... | @@ -491,6 +498,7 @@ const InstTracking = struct { |
| 491 | .register_overflow, | 498 | .register_overflow, |
| 492 | .indirect, | 499 | .indirect, |
| 493 | .reserved_frame, | 500 | .reserved_frame, |
| 501 | .air_ref, | ||
| 494 | => unreachable, | 502 | => unreachable, |
| 495 | }; | 503 | }; |
| 496 | } | 504 | } |
| ... | @@ -531,6 +539,7 @@ const InstTracking = struct { | ... | @@ -531,6 +539,7 @@ const InstTracking = struct { |
| 531 | .register_offset, | 539 | .register_offset, |
| 532 | .register_overflow, | 540 | .register_overflow, |
| 533 | .indirect, | 541 | .indirect, |
| 542 | .air_ref, | ||
| 534 | => unreachable, | 543 | => unreachable, |
| 535 | } | 544 | } |
| 536 | } | 545 | } |
| ... | @@ -1807,11 +1816,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1807,11 +1816,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1807 | .log2, | 1816 | .log2, |
| 1808 | .log10, | 1817 | .log10, |
| 1809 | .round, | 1818 | .round, |
| 1810 | => try self.airUnaryMath(inst), | 1819 | => |tag| try self.airUnaryMath(inst, tag), |
| 1811 | 1820 | ||
| 1812 | .floor => try self.airRound(inst, 0b1_0_01), | 1821 | .floor => try self.airRound(inst, .{ .mode = .down, .precision = .inexact }), |
| 1813 | .ceil => try self.airRound(inst, 0b1_0_10), | 1822 | .ceil => try self.airRound(inst, .{ .mode = .up, .precision = .inexact }), |
| 1814 | .trunc_float => try self.airRound(inst, 0b1_0_11), | 1823 | .trunc_float => try self.airRound(inst, .{ .mode = .zero, .precision = .inexact }), |
| 1815 | .sqrt => try self.airSqrt(inst), | 1824 | .sqrt => try self.airSqrt(inst), |
| 1816 | .neg => try self.airFloatSign(inst), | 1825 | .neg => try self.airFloatSign(inst), |
| 1817 | 1826 | ||
| ... | @@ -2439,7 +2448,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt | ... | @@ -2439,7 +2448,7 @@ fn restoreState(self: *Self, state: State, deaths: []const Air.Inst.Index, compt |
| 2439 | } | 2448 | } |
| 2440 | 2449 | ||
| 2441 | pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { | 2450 | pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void { |
| 2442 | const tracking = self.inst_tracking.getPtr(inst).?; | 2451 | const tracking = self.inst_tracking.getPtr(inst) orelse return; |
| 2443 | assert(tracking.getReg().?.id() == reg.id()); | 2452 | assert(tracking.getReg().?.id() == reg.id()); |
| 2444 | try tracking.spill(self, inst); | 2453 | try tracking.spill(self, inst); |
| 2445 | tracking.trackSpill(self, inst); | 2454 | tracking.trackSpill(self, inst); |
| ... | @@ -2515,63 +2524,96 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2515,63 +2524,96 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2515 | const src_ty = self.typeOf(ty_op.operand); | 2524 | const src_ty = self.typeOf(ty_op.operand); |
| 2516 | const src_bits = src_ty.floatBits(self.target.*); | 2525 | const src_bits = src_ty.floatBits(self.target.*); |
| 2517 | 2526 | ||
| 2518 | const src_mcv = try self.resolveInst(ty_op.operand); | 2527 | const result = result: { |
| 2519 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 2528 | if (switch (dst_bits) { |
| 2520 | src_mcv | 2529 | 16 => switch (src_bits) { |
| 2521 | else | 2530 | 32 => !self.hasFeature(.f16c), |
| 2522 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | 2531 | 64, 80, 128 => true, |
| 2523 | const dst_reg = dst_mcv.getReg().?.to128(); | 2532 | else => unreachable, |
| 2524 | const dst_lock = self.register_manager.lockReg(dst_reg); | 2533 | }, |
| 2525 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 2534 | 32 => switch (src_bits) { |
| 2535 | 64 => false, | ||
| 2536 | 80, 128 => true, | ||
| 2537 | else => unreachable, | ||
| 2538 | }, | ||
| 2539 | 64 => switch (src_bits) { | ||
| 2540 | 80, 128 => true, | ||
| 2541 | else => unreachable, | ||
| 2542 | }, | ||
| 2543 | 80 => switch (dst_bits) { | ||
| 2544 | 128 => true, | ||
| 2545 | else => unreachable, | ||
| 2546 | }, | ||
| 2547 | else => unreachable, | ||
| 2548 | }) { | ||
| 2549 | var callee: ["__trunc?f?f2".len]u8 = undefined; | ||
| 2550 | break :result try self.genCall(.{ .lib = .{ | ||
| 2551 | .return_type = self.floatCompilerRtAbiType(dst_ty, src_ty).toIntern(), | ||
| 2552 | .param_types = &.{self.floatCompilerRtAbiType(src_ty, dst_ty).toIntern()}, | ||
| 2553 | .callee = std.fmt.bufPrint(&callee, "__trunc{c}f{c}f2", .{ | ||
| 2554 | floatCompilerRtAbiName(src_bits), | ||
| 2555 | floatCompilerRtAbiName(dst_bits), | ||
| 2556 | }) catch unreachable, | ||
| 2557 | } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}); | ||
| 2558 | } | ||
| 2526 | 2559 | ||
| 2527 | if (dst_bits == 16 and self.hasFeature(.f16c)) { | 2560 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 2528 | switch (src_bits) { | 2561 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2529 | 32 => { | 2562 | src_mcv |
| 2530 | const mat_src_reg = if (src_mcv.isRegister()) | 2563 | else |
| 2564 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | ||
| 2565 | const dst_reg = dst_mcv.getReg().?.to128(); | ||
| 2566 | const dst_lock = self.register_manager.lockReg(dst_reg); | ||
| 2567 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 2568 | |||
| 2569 | if (dst_bits == 16) { | ||
| 2570 | assert(self.hasFeature(.f16c)); | ||
| 2571 | switch (src_bits) { | ||
| 2572 | 32 => { | ||
| 2573 | const mat_src_reg = if (src_mcv.isRegister()) | ||
| 2574 | src_mcv.getReg().? | ||
| 2575 | else | ||
| 2576 | try self.copyToTmpRegister(src_ty, src_mcv); | ||
| 2577 | try self.asmRegisterRegisterImmediate( | ||
| 2578 | .{ .v_, .cvtps2ph }, | ||
| 2579 | dst_reg, | ||
| 2580 | mat_src_reg.to128(), | ||
| 2581 | Immediate.u(0b1_00), | ||
| 2582 | ); | ||
| 2583 | }, | ||
| 2584 | else => unreachable, | ||
| 2585 | } | ||
| 2586 | } else { | ||
| 2587 | assert(src_bits == 64 and dst_bits == 32); | ||
| 2588 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | ||
| 2589 | .{ .v_ss, .cvtsd2 }, | ||
| 2590 | dst_reg, | ||
| 2591 | dst_reg, | ||
| 2592 | src_mcv.mem(.qword), | ||
| 2593 | ) else try self.asmRegisterRegisterRegister( | ||
| 2594 | .{ .v_ss, .cvtsd2 }, | ||
| 2595 | dst_reg, | ||
| 2596 | dst_reg, | ||
| 2597 | (if (src_mcv.isRegister()) | ||
| 2531 | src_mcv.getReg().? | 2598 | src_mcv.getReg().? |
| 2532 | else | 2599 | else |
| 2533 | try self.copyToTmpRegister(src_ty, src_mcv); | 2600 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), |
| 2534 | try self.asmRegisterRegisterImmediate( | 2601 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 2535 | .{ .v_, .cvtps2ph }, | 2602 | .{ ._ss, .cvtsd2 }, |
| 2536 | dst_reg, | 2603 | dst_reg, |
| 2537 | mat_src_reg.to128(), | 2604 | src_mcv.mem(.qword), |
| 2538 | Immediate.u(0b1_00), | 2605 | ) else try self.asmRegisterRegister( |
| 2539 | ); | 2606 | .{ ._ss, .cvtsd2 }, |
| 2540 | }, | 2607 | dst_reg, |
| 2541 | else => return self.fail("TODO implement airFptrunc from {} to {}", .{ | 2608 | (if (src_mcv.isRegister()) |
| 2542 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 2609 | src_mcv.getReg().? |
| 2543 | }), | 2610 | else |
| 2611 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | ||
| 2612 | ); | ||
| 2544 | } | 2613 | } |
| 2545 | } else if (src_bits == 64 and dst_bits == 32) { | 2614 | break :result dst_mcv; |
| 2546 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | 2615 | }; |
| 2547 | .{ .v_ss, .cvtsd2 }, | 2616 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2548 | dst_reg, | ||
| 2549 | dst_reg, | ||
| 2550 | src_mcv.mem(.qword), | ||
| 2551 | ) else try self.asmRegisterRegisterRegister( | ||
| 2552 | .{ .v_ss, .cvtsd2 }, | ||
| 2553 | dst_reg, | ||
| 2554 | dst_reg, | ||
| 2555 | (if (src_mcv.isRegister()) | ||
| 2556 | src_mcv.getReg().? | ||
| 2557 | else | ||
| 2558 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | ||
| 2559 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 2560 | .{ ._ss, .cvtsd2 }, | ||
| 2561 | dst_reg, | ||
| 2562 | src_mcv.mem(.qword), | ||
| 2563 | ) else try self.asmRegisterRegister( | ||
| 2564 | .{ ._ss, .cvtsd2 }, | ||
| 2565 | dst_reg, | ||
| 2566 | (if (src_mcv.isRegister()) | ||
| 2567 | src_mcv.getReg().? | ||
| 2568 | else | ||
| 2569 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | ||
| 2570 | ); | ||
| 2571 | } else return self.fail("TODO implement airFptrunc from {} to {}", .{ | ||
| 2572 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | ||
| 2573 | }); | ||
| 2574 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | ||
| 2575 | } | 2617 | } |
| 2576 | 2618 | ||
| 2577 | fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | 2619 | fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -2581,58 +2623,96 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2581,58 +2623,96 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2581 | const src_ty = self.typeOf(ty_op.operand); | 2623 | const src_ty = self.typeOf(ty_op.operand); |
| 2582 | const src_bits = src_ty.floatBits(self.target.*); | 2624 | const src_bits = src_ty.floatBits(self.target.*); |
| 2583 | 2625 | ||
| 2584 | const src_mcv = try self.resolveInst(ty_op.operand); | 2626 | const result = result: { |
| 2585 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 2627 | if (switch (src_bits) { |
| 2586 | src_mcv | 2628 | 16 => switch (dst_bits) { |
| 2587 | else | 2629 | 32, 64 => !self.hasFeature(.f16c), |
| 2588 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | 2630 | 80, 128 => true, |
| 2589 | const dst_reg = dst_mcv.getReg().?.to128(); | 2631 | else => unreachable, |
| 2590 | const dst_lock = self.register_manager.lockReg(dst_reg); | 2632 | }, |
| 2591 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 2633 | 32 => switch (dst_bits) { |
| 2634 | 64 => false, | ||
| 2635 | 80, 128 => true, | ||
| 2636 | else => unreachable, | ||
| 2637 | }, | ||
| 2638 | 64 => switch (dst_bits) { | ||
| 2639 | 80, 128 => true, | ||
| 2640 | else => unreachable, | ||
| 2641 | }, | ||
| 2642 | 80 => switch (dst_bits) { | ||
| 2643 | 128 => true, | ||
| 2644 | else => unreachable, | ||
| 2645 | }, | ||
| 2646 | else => unreachable, | ||
| 2647 | }) { | ||
| 2648 | var callee: ["__extend?f?f2".len]u8 = undefined; | ||
| 2649 | break :result try self.genCall(.{ .lib = .{ | ||
| 2650 | .return_type = self.floatCompilerRtAbiType(dst_ty, src_ty).toIntern(), | ||
| 2651 | .param_types = &.{self.floatCompilerRtAbiType(src_ty, dst_ty).toIntern()}, | ||
| 2652 | .callee = std.fmt.bufPrint(&callee, "__extend{c}f{c}f2", .{ | ||
| 2653 | floatCompilerRtAbiName(src_bits), | ||
| 2654 | floatCompilerRtAbiName(dst_bits), | ||
| 2655 | }) catch unreachable, | ||
| 2656 | } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}); | ||
| 2657 | } | ||
| 2592 | 2658 | ||
| 2593 | if (src_bits == 16 and self.hasFeature(.f16c)) { | 2659 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 2594 | const mat_src_reg = if (src_mcv.isRegister()) | 2660 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2595 | src_mcv.getReg().? | 2661 | src_mcv |
| 2596 | else | 2662 | else |
| 2597 | try self.copyToTmpRegister(src_ty, src_mcv); | 2663 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 2598 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, mat_src_reg.to128()); | 2664 | const dst_reg = dst_mcv.getReg().?.to128(); |
| 2599 | switch (dst_bits) { | 2665 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 2600 | 32 => {}, | 2666 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 2601 | 64 => try self.asmRegisterRegisterRegister(.{ .v_sd, .cvtss2 }, dst_reg, dst_reg, dst_reg), | 2667 | |
| 2602 | else => return self.fail("TODO implement airFpext from {} to {}", .{ | 2668 | if (src_bits == 16) { |
| 2603 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 2669 | assert(self.hasFeature(.f16c)); |
| 2604 | }), | 2670 | const mat_src_reg = if (src_mcv.isRegister()) |
| 2605 | } | ||
| 2606 | } else if (src_bits == 32 and dst_bits == 64) { | ||
| 2607 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | ||
| 2608 | .{ .v_sd, .cvtss2 }, | ||
| 2609 | dst_reg, | ||
| 2610 | dst_reg, | ||
| 2611 | src_mcv.mem(.dword), | ||
| 2612 | ) else try self.asmRegisterRegisterRegister( | ||
| 2613 | .{ .v_sd, .cvtss2 }, | ||
| 2614 | dst_reg, | ||
| 2615 | dst_reg, | ||
| 2616 | (if (src_mcv.isRegister()) | ||
| 2617 | src_mcv.getReg().? | ||
| 2618 | else | ||
| 2619 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | ||
| 2620 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 2621 | .{ ._sd, .cvtss2 }, | ||
| 2622 | dst_reg, | ||
| 2623 | src_mcv.mem(.dword), | ||
| 2624 | ) else try self.asmRegisterRegister( | ||
| 2625 | .{ ._sd, .cvtss2 }, | ||
| 2626 | dst_reg, | ||
| 2627 | (if (src_mcv.isRegister()) | ||
| 2628 | src_mcv.getReg().? | 2671 | src_mcv.getReg().? |
| 2629 | else | 2672 | else |
| 2630 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | 2673 | try self.copyToTmpRegister(src_ty, src_mcv); |
| 2631 | ); | 2674 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, mat_src_reg.to128()); |
| 2632 | } else return self.fail("TODO implement airFpext from {} to {}", .{ | 2675 | switch (dst_bits) { |
| 2633 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 2676 | 32 => {}, |
| 2634 | }); | 2677 | 64 => try self.asmRegisterRegisterRegister( |
| 2635 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 2678 | .{ .v_sd, .cvtss2 }, |
| 2679 | dst_reg, | ||
| 2680 | dst_reg, | ||
| 2681 | dst_reg, | ||
| 2682 | ), | ||
| 2683 | else => unreachable, | ||
| 2684 | } | ||
| 2685 | } else { | ||
| 2686 | assert(src_bits == 32 and dst_bits == 64); | ||
| 2687 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | ||
| 2688 | .{ .v_sd, .cvtss2 }, | ||
| 2689 | dst_reg, | ||
| 2690 | dst_reg, | ||
| 2691 | src_mcv.mem(.dword), | ||
| 2692 | ) else try self.asmRegisterRegisterRegister( | ||
| 2693 | .{ .v_sd, .cvtss2 }, | ||
| 2694 | dst_reg, | ||
| 2695 | dst_reg, | ||
| 2696 | (if (src_mcv.isRegister()) | ||
| 2697 | src_mcv.getReg().? | ||
| 2698 | else | ||
| 2699 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | ||
| 2700 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 2701 | .{ ._sd, .cvtss2 }, | ||
| 2702 | dst_reg, | ||
| 2703 | src_mcv.mem(.dword), | ||
| 2704 | ) else try self.asmRegisterRegister( | ||
| 2705 | .{ ._sd, .cvtss2 }, | ||
| 2706 | dst_reg, | ||
| 2707 | (if (src_mcv.isRegister()) | ||
| 2708 | src_mcv.getReg().? | ||
| 2709 | else | ||
| 2710 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | ||
| 2711 | ); | ||
| 2712 | } | ||
| 2713 | break :result dst_mcv; | ||
| 2714 | }; | ||
| 2715 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | ||
| 2636 | } | 2716 | } |
| 2637 | 2717 | ||
| 2638 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { | 2718 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -5002,7 +5082,26 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5002,7 +5082,26 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { |
| 5002 | return self.floatSign(inst, un_op, ty); | 5082 | return self.floatSign(inst, un_op, ty); |
| 5003 | } | 5083 | } |
| 5004 | 5084 | ||
| 5005 | fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void { | 5085 | const RoundMode = packed struct(u5) { |
| 5086 | mode: enum(u4) { | ||
| 5087 | /// Round to nearest (even) | ||
| 5088 | nearest = 0b0_00, | ||
| 5089 | /// Round down (toward -∞) | ||
| 5090 | down = 0b0_01, | ||
| 5091 | /// Round up (toward +∞) | ||
| 5092 | up = 0b0_10, | ||
| 5093 | /// Round toward zero (truncate) | ||
| 5094 | zero = 0b0_11, | ||
| 5095 | /// Use current rounding mode of MXCSR.RC | ||
| 5096 | mxcsr = 0b1_00, | ||
| 5097 | }, | ||
| 5098 | precision: enum(u1) { | ||
| 5099 | normal = 0b0, | ||
| 5100 | inexact = 0b1, | ||
| 5101 | }, | ||
| 5102 | }; | ||
| 5103 | |||
| 5104 | fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void { | ||
| 5006 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 5105 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 5007 | const ty = self.typeOf(un_op); | 5106 | const ty = self.typeOf(un_op); |
| 5008 | 5107 | ||
| ... | @@ -5018,12 +5117,9 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void { | ... | @@ -5018,12 +5117,9 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void { |
| 5018 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); | 5117 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); |
| 5019 | } | 5118 | } |
| 5020 | 5119 | ||
| 5021 | fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4) !void { | 5120 | fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void { |
| 5022 | const mod = self.bin_file.options.module.?; | 5121 | const mod = self.bin_file.options.module.?; |
| 5023 | if (!self.hasFeature(.sse4_1)) | 5122 | const mir_tag = @as(?Mir.Inst.FixedTag, if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) { |
| 5024 | return self.fail("TODO implement genRound without sse4_1 feature", .{}); | ||
| 5025 | |||
| 5026 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { | ||
| 5027 | .Float => switch (ty.floatBits(self.target.*)) { | 5123 | .Float => switch (ty.floatBits(self.target.*)) { |
| 5028 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, | 5124 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, |
| 5029 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round }, | 5125 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round }, |
| ... | @@ -5050,9 +5146,28 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 | ... | @@ -5050,9 +5146,28 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 |
| 5050 | else => null, | 5146 | else => null, |
| 5051 | }, | 5147 | }, |
| 5052 | else => unreachable, | 5148 | else => unreachable, |
| 5053 | }) orelse return self.fail("TODO implement genRound for {}", .{ | 5149 | } else null) orelse { |
| 5054 | ty.fmt(self.bin_file.options.module.?), | 5150 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement genRound for {}", .{ |
| 5055 | }); | 5151 | ty.fmt(self.bin_file.options.module.?), |
| 5152 | }); | ||
| 5153 | |||
| 5154 | var callee: ["__trunc?".len]u8 = undefined; | ||
| 5155 | const res = try self.genCall(.{ .lib = .{ | ||
| 5156 | .return_type = ty.toIntern(), | ||
| 5157 | .param_types = &.{ty.toIntern()}, | ||
| 5158 | .callee = std.fmt.bufPrint(&callee, "{s}{s}{s}", .{ | ||
| 5159 | floatLibcAbiPrefix(ty), | ||
| 5160 | switch (mode.mode) { | ||
| 5161 | .down => "floor", | ||
| 5162 | .up => "ceil", | ||
| 5163 | .zero => "trunc", | ||
| 5164 | else => unreachable, | ||
| 5165 | }, | ||
| 5166 | floatLibcAbiSuffix(ty), | ||
| 5167 | }) catch unreachable, | ||
| 5168 | } }, &.{ty}, &.{src_mcv}); | ||
| 5169 | return self.genSetReg(dst_reg, ty, res); | ||
| 5170 | }; | ||
| 5056 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | 5171 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 5057 | const dst_alias = registerAlias(dst_reg, abi_size); | 5172 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 5058 | switch (mir_tag[0]) { | 5173 | switch (mir_tag[0]) { |
| ... | @@ -5061,7 +5176,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 | ... | @@ -5061,7 +5176,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 |
| 5061 | dst_alias, | 5176 | dst_alias, |
| 5062 | dst_alias, | 5177 | dst_alias, |
| 5063 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 5178 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), |
| 5064 | Immediate.u(mode), | 5179 | Immediate.u(@as(u5, @bitCast(mode))), |
| 5065 | ) else try self.asmRegisterRegisterRegisterImmediate( | 5180 | ) else try self.asmRegisterRegisterRegisterImmediate( |
| 5066 | mir_tag, | 5181 | mir_tag, |
| 5067 | dst_alias, | 5182 | dst_alias, |
| ... | @@ -5070,13 +5185,13 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 | ... | @@ -5070,13 +5185,13 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 |
| 5070 | src_mcv.getReg().? | 5185 | src_mcv.getReg().? |
| 5071 | else | 5186 | else |
| 5072 | try self.copyToTmpRegister(ty, src_mcv), abi_size), | 5187 | try self.copyToTmpRegister(ty, src_mcv), abi_size), |
| 5073 | Immediate.u(mode), | 5188 | Immediate.u(@as(u5, @bitCast(mode))), |
| 5074 | ), | 5189 | ), |
| 5075 | else => if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 5190 | else => if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 5076 | mir_tag, | 5191 | mir_tag, |
| 5077 | dst_alias, | 5192 | dst_alias, |
| 5078 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | 5193 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), |
| 5079 | Immediate.u(mode), | 5194 | Immediate.u(@as(u5, @bitCast(mode))), |
| 5080 | ) else try self.asmRegisterRegisterImmediate( | 5195 | ) else try self.asmRegisterRegisterImmediate( |
| 5081 | mir_tag, | 5196 | mir_tag, |
| 5082 | dst_alias, | 5197 | dst_alias, |
| ... | @@ -5084,7 +5199,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 | ... | @@ -5084,7 +5199,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 |
| 5084 | src_mcv.getReg().? | 5199 | src_mcv.getReg().? |
| 5085 | else | 5200 | else |
| 5086 | try self.copyToTmpRegister(ty, src_mcv), abi_size), | 5201 | try self.copyToTmpRegister(ty, src_mcv), abi_size), |
| 5087 | Immediate.u(mode), | 5202 | Immediate.u(@as(u5, @bitCast(mode))), |
| 5088 | ), | 5203 | ), |
| 5089 | } | 5204 | } |
| 5090 | } | 5205 | } |
| ... | @@ -5244,9 +5359,21 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5244,9 +5359,21 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 5244 | else => unreachable, | 5359 | else => unreachable, |
| 5245 | }, | 5360 | }, |
| 5246 | else => unreachable, | 5361 | else => unreachable, |
| 5247 | }) orelse return self.fail("TODO implement airSqrt for {}", .{ | 5362 | }) orelse { |
| 5248 | ty.fmt(mod), | 5363 | if (ty.zigTypeTag(mod) != .Float) return self.fail("TODO implement airSqrt for {}", .{ |
| 5249 | }); | 5364 | ty.fmt(mod), |
| 5365 | }); | ||
| 5366 | |||
| 5367 | var callee: ["__sqrt?".len]u8 = undefined; | ||
| 5368 | break :result try self.genCall(.{ .lib = .{ | ||
| 5369 | .return_type = ty.toIntern(), | ||
| 5370 | .param_types = &.{ty.toIntern()}, | ||
| 5371 | .callee = std.fmt.bufPrint(&callee, "{s}sqrt{s}", .{ | ||
| 5372 | floatLibcAbiPrefix(ty), | ||
| 5373 | floatLibcAbiSuffix(ty), | ||
| 5374 | }) catch unreachable, | ||
| 5375 | } }, &.{ty}, &.{src_mcv}); | ||
| 5376 | }; | ||
| 5250 | switch (mir_tag[0]) { | 5377 | switch (mir_tag[0]) { |
| 5251 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | 5378 | .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( |
| 5252 | mir_tag, | 5379 | mir_tag, |
| ... | @@ -5280,13 +5407,32 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5280,13 +5407,32 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 5280 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 5407 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 5281 | } | 5408 | } |
| 5282 | 5409 | ||
| 5283 | fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void { | 5410 | fn airUnaryMath(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 5284 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 5411 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 5285 | _ = un_op; | 5412 | const ty = self.typeOf(un_op); |
| 5286 | return self.fail("TODO implement airUnaryMath for {}", .{ | 5413 | var callee: ["__round?".len]u8 = undefined; |
| 5287 | self.air.instructions.items(.tag)[inst], | 5414 | const result = try self.genCall(.{ .lib = .{ |
| 5288 | }); | 5415 | .return_type = ty.toIntern(), |
| 5289 | //return self.finishAir(inst, result, .{ un_op, .none, .none }); | 5416 | .param_types = &.{ty.toIntern()}, |
| 5417 | .callee = std.fmt.bufPrint(&callee, "{s}{s}{s}", .{ | ||
| 5418 | floatLibcAbiPrefix(ty), | ||
| 5419 | switch (tag) { | ||
| 5420 | .sin, | ||
| 5421 | .cos, | ||
| 5422 | .tan, | ||
| 5423 | .exp, | ||
| 5424 | .exp2, | ||
| 5425 | .log, | ||
| 5426 | .log2, | ||
| 5427 | .log10, | ||
| 5428 | .round, | ||
| 5429 | => @tagName(tag), | ||
| 5430 | else => unreachable, | ||
| 5431 | }, | ||
| 5432 | floatLibcAbiSuffix(ty), | ||
| 5433 | }) catch unreachable, | ||
| 5434 | } }, &.{ty}, &.{.{ .air_ref = un_op }}); | ||
| 5435 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | ||
| 5290 | } | 5436 | } |
| 5291 | 5437 | ||
| 5292 | fn reuseOperand( | 5438 | fn reuseOperand( |
| ... | @@ -5439,6 +5585,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro | ... | @@ -5439,6 +5585,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 5439 | 5585 | ||
| 5440 | try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); | 5586 | try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); |
| 5441 | }, | 5587 | }, |
| 5588 | .air_ref => |ref| try self.load(dst_mcv, ptr_ty, try self.resolveInst(ref)), | ||
| 5442 | } | 5589 | } |
| 5443 | } | 5590 | } |
| 5444 | 5591 | ||
| ... | @@ -5584,6 +5731,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr | ... | @@ -5584,6 +5731,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr |
| 5584 | 5731 | ||
| 5585 | try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv); | 5732 | try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv); |
| 5586 | }, | 5733 | }, |
| 5734 | .air_ref => |ref| try self.store(ptr_ty, ptr_mcv, try self.resolveInst(ref)), | ||
| 5587 | } | 5735 | } |
| 5588 | } | 5736 | } |
| 5589 | 5737 | ||
| ... | @@ -5925,6 +6073,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC | ... | @@ -5925,6 +6073,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC |
| 5925 | .lea_tlv, | 6073 | .lea_tlv, |
| 5926 | .lea_frame, | 6074 | .lea_frame, |
| 5927 | .reserved_frame, | 6075 | .reserved_frame, |
| 6076 | .air_ref, | ||
| 5928 | => unreachable, // unmodifiable destination | 6077 | => unreachable, // unmodifiable destination |
| 5929 | .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), | 6078 | .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), |
| 5930 | .memory, .load_got, .load_direct, .load_tlv => { | 6079 | .memory, .load_got, .load_direct, .load_tlv => { |
| ... | @@ -6433,6 +6582,34 @@ fn genBinOp( | ... | @@ -6433,6 +6582,34 @@ fn genBinOp( |
| 6433 | const lhs_ty = self.typeOf(lhs_air); | 6582 | const lhs_ty = self.typeOf(lhs_air); |
| 6434 | const rhs_ty = self.typeOf(rhs_air); | 6583 | const rhs_ty = self.typeOf(rhs_air); |
| 6435 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 6584 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); |
| 6585 | |||
| 6586 | if (lhs_ty.isRuntimeFloat() and switch (lhs_ty.floatBits(self.target.*)) { | ||
| 6587 | 16 => !self.hasFeature(.f16c), | ||
| 6588 | 32, 64 => false, | ||
| 6589 | 80, 128 => true, | ||
| 6590 | else => unreachable, | ||
| 6591 | }) { | ||
| 6592 | var callee: ["__add?f3".len]u8 = undefined; | ||
| 6593 | return self.genCall(.{ .lib = .{ | ||
| 6594 | .return_type = lhs_ty.toIntern(), | ||
| 6595 | .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() }, | ||
| 6596 | .callee = switch (air_tag) { | ||
| 6597 | .add, .sub, .mul, .div_float => std.fmt.bufPrint(&callee, "__{s}{c}f3", .{ | ||
| 6598 | @tagName(air_tag)[0..3], | ||
| 6599 | floatCompilerRtAbiName(lhs_ty.floatBits(self.target.*)), | ||
| 6600 | }), | ||
| 6601 | .min, .max => std.fmt.bufPrint(&callee, "{s}f{s}{s}", .{ | ||
| 6602 | floatLibcAbiPrefix(lhs_ty), | ||
| 6603 | @tagName(air_tag), | ||
| 6604 | floatLibcAbiSuffix(lhs_ty), | ||
| 6605 | }), | ||
| 6606 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ | ||
| 6607 | @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?), | ||
| 6608 | }), | ||
| 6609 | } catch unreachable, | ||
| 6610 | } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }); | ||
| 6611 | } | ||
| 6612 | |||
| 6436 | if ((lhs_ty.scalarType(mod).isRuntimeFloat() and | 6613 | if ((lhs_ty.scalarType(mod).isRuntimeFloat() and |
| 6437 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or | 6614 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or |
| 6438 | lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)) | 6615 | lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)) |
| ... | @@ -6584,7 +6761,11 @@ fn genBinOp( | ... | @@ -6584,7 +6761,11 @@ fn genBinOp( |
| 6584 | .min, | 6761 | .min, |
| 6585 | .max, | 6762 | .max, |
| 6586 | => { | 6763 | => { |
| 6587 | const mat_src_mcv: MCValue = if (switch (src_mcv) { | 6764 | const resolved_src_mcv = switch (src_mcv) { |
| 6765 | else => src_mcv, | ||
| 6766 | .air_ref => |ref| try self.resolveInst(ref), | ||
| 6767 | }; | ||
| 6768 | const mat_src_mcv: MCValue = if (switch (resolved_src_mcv) { | ||
| 6588 | .immediate, | 6769 | .immediate, |
| 6589 | .eflags, | 6770 | .eflags, |
| 6590 | .register_offset, | 6771 | .register_offset, |
| ... | @@ -6598,7 +6779,10 @@ fn genBinOp( | ... | @@ -6598,7 +6779,10 @@ fn genBinOp( |
| 6598 | => true, | 6779 | => true, |
| 6599 | .memory => |addr| math.cast(i32, @as(i64, @bitCast(addr))) == null, | 6780 | .memory => |addr| math.cast(i32, @as(i64, @bitCast(addr))) == null, |
| 6600 | else => false, | 6781 | else => false, |
| 6601 | }) .{ .register = try self.copyToTmpRegister(rhs_ty, src_mcv) } else src_mcv; | 6782 | }) |
| 6783 | .{ .register = try self.copyToTmpRegister(rhs_ty, resolved_src_mcv) } | ||
| 6784 | else | ||
| 6785 | resolved_src_mcv; | ||
| 6602 | const mat_mcv_lock = switch (mat_src_mcv) { | 6786 | const mat_mcv_lock = switch (mat_src_mcv) { |
| 6603 | .register => |reg| self.register_manager.lockReg(reg), | 6787 | .register => |reg| self.register_manager.lockReg(reg), |
| 6604 | else => null, | 6788 | else => null, |
| ... | @@ -6645,6 +6829,7 @@ fn genBinOp( | ... | @@ -6645,6 +6829,7 @@ fn genBinOp( |
| 6645 | .lea_tlv, | 6829 | .lea_tlv, |
| 6646 | .lea_frame, | 6830 | .lea_frame, |
| 6647 | .reserved_frame, | 6831 | .reserved_frame, |
| 6832 | .air_ref, | ||
| 6648 | => unreachable, | 6833 | => unreachable, |
| 6649 | .register => |src_reg| try self.asmCmovccRegisterRegister( | 6834 | .register => |src_reg| try self.asmCmovccRegisterRegister( |
| 6650 | registerAlias(tmp_reg, cmov_abi_size), | 6835 | registerAlias(tmp_reg, cmov_abi_size), |
| ... | @@ -6685,7 +6870,8 @@ fn genBinOp( | ... | @@ -6685,7 +6870,8 @@ fn genBinOp( |
| 6685 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | 6870 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { |
| 6686 | else => unreachable, | 6871 | else => unreachable, |
| 6687 | .Float => switch (lhs_ty.floatBits(self.target.*)) { | 6872 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 6688 | 16 => if (self.hasFeature(.f16c)) { | 6873 | 16 => { |
| 6874 | assert(self.hasFeature(.f16c)); | ||
| 6689 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 6875 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 6690 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 6876 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 6691 | defer self.register_manager.unlockReg(tmp_lock); | 6877 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -6728,7 +6914,7 @@ fn genBinOp( | ... | @@ -6728,7 +6914,7 @@ fn genBinOp( |
| 6728 | Immediate.u(0b1_00), | 6914 | Immediate.u(0b1_00), |
| 6729 | ); | 6915 | ); |
| 6730 | return dst_mcv; | 6916 | return dst_mcv; |
| 6731 | } else null, | 6917 | }, |
| 6732 | 32 => switch (air_tag) { | 6918 | 32 => switch (air_tag) { |
| 6733 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, | 6919 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, |
| 6734 | .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, | 6920 | .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, |
| ... | @@ -6989,181 +7175,184 @@ fn genBinOp( | ... | @@ -6989,181 +7175,184 @@ fn genBinOp( |
| 6989 | else => null, | 7175 | else => null, |
| 6990 | }, | 7176 | }, |
| 6991 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | 7177 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { |
| 6992 | 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen(mod)) { | 7178 | 16 => tag: { |
| 6993 | 1 => { | 7179 | assert(self.hasFeature(.f16c)); |
| 6994 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 7180 | switch (lhs_ty.vectorLen(mod)) { |
| 6995 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7181 | 1 => { |
| 6996 | defer self.register_manager.unlockReg(tmp_lock); | 7182 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 7183 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 7184 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 6997 | 7185 | ||
| 6998 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( | 7186 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( |
| 6999 | .{ .vp_w, .insr }, | 7187 | .{ .vp_w, .insr }, |
| 7000 | dst_reg, | 7188 | dst_reg, |
| 7001 | dst_reg, | 7189 | dst_reg, |
| 7002 | src_mcv.mem(.word), | 7190 | src_mcv.mem(.word), |
| 7003 | Immediate.u(1), | 7191 | Immediate.u(1), |
| 7004 | ) else try self.asmRegisterRegisterRegister( | 7192 | ) else try self.asmRegisterRegisterRegister( |
| 7005 | .{ .vp_, .unpcklwd }, | 7193 | .{ .vp_, .unpcklwd }, |
| 7006 | dst_reg, | 7194 | dst_reg, |
| 7007 | dst_reg, | 7195 | dst_reg, |
| 7008 | (if (src_mcv.isRegister()) | 7196 | (if (src_mcv.isRegister()) |
| 7009 | src_mcv.getReg().? | 7197 | src_mcv.getReg().? |
| 7010 | else | 7198 | else |
| 7011 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7199 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7012 | ); | 7200 | ); |
| 7013 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); | 7201 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 7014 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); | 7202 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); |
| 7015 | try self.asmRegisterRegisterRegister( | 7203 | try self.asmRegisterRegisterRegister( |
| 7016 | switch (air_tag) { | 7204 | switch (air_tag) { |
| 7017 | .add => .{ .v_ss, .add }, | 7205 | .add => .{ .v_ss, .add }, |
| 7018 | .sub => .{ .v_ss, .sub }, | 7206 | .sub => .{ .v_ss, .sub }, |
| 7019 | .mul => .{ .v_ss, .mul }, | 7207 | .mul => .{ .v_ss, .mul }, |
| 7020 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, | 7208 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, |
| 7021 | .max => .{ .v_ss, .max }, | 7209 | .max => .{ .v_ss, .max }, |
| 7022 | .min => .{ .v_ss, .max }, | 7210 | .min => .{ .v_ss, .max }, |
| 7023 | else => unreachable, | 7211 | else => unreachable, |
| 7024 | }, | 7212 | }, |
| 7025 | dst_reg, | 7213 | dst_reg, |
| 7026 | dst_reg, | 7214 | dst_reg, |
| 7027 | tmp_reg, | 7215 | tmp_reg, |
| 7028 | ); | 7216 | ); |
| 7029 | try self.asmRegisterRegisterImmediate( | 7217 | try self.asmRegisterRegisterImmediate( |
| 7030 | .{ .v_, .cvtps2ph }, | 7218 | .{ .v_, .cvtps2ph }, |
| 7031 | dst_reg, | 7219 | dst_reg, |
| 7032 | dst_reg, | 7220 | dst_reg, |
| 7033 | Immediate.u(0b1_00), | 7221 | Immediate.u(0b1_00), |
| 7034 | ); | 7222 | ); |
| 7035 | return dst_mcv; | 7223 | return dst_mcv; |
| 7036 | }, | 7224 | }, |
| 7037 | 2 => { | 7225 | 2 => { |
| 7038 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 7226 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 7039 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7227 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7040 | defer self.register_manager.unlockReg(tmp_lock); | 7228 | defer self.register_manager.unlockReg(tmp_lock); |
| 7041 | 7229 | ||
| 7042 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 7230 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 7043 | .{ .vp_d, .insr }, | 7231 | .{ .vp_d, .insr }, |
| 7044 | dst_reg, | 7232 | dst_reg, |
| 7045 | src_mcv.mem(.dword), | 7233 | src_mcv.mem(.dword), |
| 7046 | Immediate.u(1), | 7234 | Immediate.u(1), |
| 7047 | ) else try self.asmRegisterRegisterRegister( | 7235 | ) else try self.asmRegisterRegisterRegister( |
| 7048 | .{ .v_ps, .unpckl }, | 7236 | .{ .v_ps, .unpckl }, |
| 7049 | dst_reg, | 7237 | dst_reg, |
| 7050 | dst_reg, | 7238 | dst_reg, |
| 7051 | (if (src_mcv.isRegister()) | 7239 | (if (src_mcv.isRegister()) |
| 7052 | src_mcv.getReg().? | 7240 | src_mcv.getReg().? |
| 7053 | else | 7241 | else |
| 7054 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7242 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7055 | ); | 7243 | ); |
| 7056 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); | 7244 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 7057 | try self.asmRegisterRegisterRegister( | 7245 | try self.asmRegisterRegisterRegister( |
| 7058 | .{ .v_ps, .movhl }, | 7246 | .{ .v_ps, .movhl }, |
| 7059 | tmp_reg, | 7247 | tmp_reg, |
| 7060 | dst_reg, | 7248 | dst_reg, |
| 7061 | dst_reg, | 7249 | dst_reg, |
| 7062 | ); | 7250 | ); |
| 7063 | try self.asmRegisterRegisterRegister( | 7251 | try self.asmRegisterRegisterRegister( |
| 7064 | switch (air_tag) { | 7252 | switch (air_tag) { |
| 7065 | .add => .{ .v_ps, .add }, | 7253 | .add => .{ .v_ps, .add }, |
| 7066 | .sub => .{ .v_ps, .sub }, | 7254 | .sub => .{ .v_ps, .sub }, |
| 7067 | .mul => .{ .v_ps, .mul }, | 7255 | .mul => .{ .v_ps, .mul }, |
| 7068 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 7256 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 7069 | .max => .{ .v_ps, .max }, | 7257 | .max => .{ .v_ps, .max }, |
| 7070 | .min => .{ .v_ps, .max }, | 7258 | .min => .{ .v_ps, .max }, |
| 7071 | else => unreachable, | 7259 | else => unreachable, |
| 7072 | }, | 7260 | }, |
| 7073 | dst_reg, | 7261 | dst_reg, |
| 7074 | dst_reg, | 7262 | dst_reg, |
| 7075 | tmp_reg, | 7263 | tmp_reg, |
| 7076 | ); | 7264 | ); |
| 7077 | try self.asmRegisterRegisterImmediate( | 7265 | try self.asmRegisterRegisterImmediate( |
| 7078 | .{ .v_, .cvtps2ph }, | 7266 | .{ .v_, .cvtps2ph }, |
| 7079 | dst_reg, | 7267 | dst_reg, |
| 7080 | dst_reg, | 7268 | dst_reg, |
| 7081 | Immediate.u(0b1_00), | 7269 | Immediate.u(0b1_00), |
| 7082 | ); | 7270 | ); |
| 7083 | return dst_mcv; | 7271 | return dst_mcv; |
| 7084 | }, | 7272 | }, |
| 7085 | 3...4 => { | 7273 | 3...4 => { |
| 7086 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 7274 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 7087 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7275 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7088 | defer self.register_manager.unlockReg(tmp_lock); | 7276 | defer self.register_manager.unlockReg(tmp_lock); |
| 7089 | 7277 | ||
| 7090 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); | 7278 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 7091 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 7279 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7092 | .{ .v_ps, .cvtph2 }, | 7280 | .{ .v_ps, .cvtph2 }, |
| 7093 | tmp_reg, | 7281 | tmp_reg, |
| 7094 | src_mcv.mem(.qword), | 7282 | src_mcv.mem(.qword), |
| 7095 | ) else try self.asmRegisterRegister( | 7283 | ) else try self.asmRegisterRegister( |
| 7096 | .{ .v_ps, .cvtph2 }, | 7284 | .{ .v_ps, .cvtph2 }, |
| 7097 | tmp_reg, | 7285 | tmp_reg, |
| 7098 | (if (src_mcv.isRegister()) | 7286 | (if (src_mcv.isRegister()) |
| 7099 | src_mcv.getReg().? | 7287 | src_mcv.getReg().? |
| 7100 | else | 7288 | else |
| 7101 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7289 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7102 | ); | 7290 | ); |
| 7103 | try self.asmRegisterRegisterRegister( | 7291 | try self.asmRegisterRegisterRegister( |
| 7104 | switch (air_tag) { | 7292 | switch (air_tag) { |
| 7105 | .add => .{ .v_ps, .add }, | 7293 | .add => .{ .v_ps, .add }, |
| 7106 | .sub => .{ .v_ps, .sub }, | 7294 | .sub => .{ .v_ps, .sub }, |
| 7107 | .mul => .{ .v_ps, .mul }, | 7295 | .mul => .{ .v_ps, .mul }, |
| 7108 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 7296 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 7109 | .max => .{ .v_ps, .max }, | 7297 | .max => .{ .v_ps, .max }, |
| 7110 | .min => .{ .v_ps, .max }, | 7298 | .min => .{ .v_ps, .max }, |
| 7111 | else => unreachable, | 7299 | else => unreachable, |
| 7112 | }, | 7300 | }, |
| 7113 | dst_reg, | 7301 | dst_reg, |
| 7114 | dst_reg, | 7302 | dst_reg, |
| 7115 | tmp_reg, | 7303 | tmp_reg, |
| 7116 | ); | 7304 | ); |
| 7117 | try self.asmRegisterRegisterImmediate( | 7305 | try self.asmRegisterRegisterImmediate( |
| 7118 | .{ .v_, .cvtps2ph }, | 7306 | .{ .v_, .cvtps2ph }, |
| 7119 | dst_reg, | 7307 | dst_reg, |
| 7120 | dst_reg, | 7308 | dst_reg, |
| 7121 | Immediate.u(0b1_00), | 7309 | Immediate.u(0b1_00), |
| 7122 | ); | 7310 | ); |
| 7123 | return dst_mcv; | 7311 | return dst_mcv; |
| 7124 | }, | 7312 | }, |
| 7125 | 5...8 => { | 7313 | 5...8 => { |
| 7126 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); | 7314 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); |
| 7127 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7315 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7128 | defer self.register_manager.unlockReg(tmp_lock); | 7316 | defer self.register_manager.unlockReg(tmp_lock); |
| 7129 | 7317 | ||
| 7130 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); | 7318 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); |
| 7131 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 7319 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7132 | .{ .v_ps, .cvtph2 }, | 7320 | .{ .v_ps, .cvtph2 }, |
| 7133 | tmp_reg, | 7321 | tmp_reg, |
| 7134 | src_mcv.mem(.xword), | 7322 | src_mcv.mem(.xword), |
| 7135 | ) else try self.asmRegisterRegister( | 7323 | ) else try self.asmRegisterRegister( |
| 7136 | .{ .v_ps, .cvtph2 }, | 7324 | .{ .v_ps, .cvtph2 }, |
| 7137 | tmp_reg, | 7325 | tmp_reg, |
| 7138 | (if (src_mcv.isRegister()) | 7326 | (if (src_mcv.isRegister()) |
| 7139 | src_mcv.getReg().? | 7327 | src_mcv.getReg().? |
| 7140 | else | 7328 | else |
| 7141 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7329 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7142 | ); | 7330 | ); |
| 7143 | try self.asmRegisterRegisterRegister( | 7331 | try self.asmRegisterRegisterRegister( |
| 7144 | switch (air_tag) { | 7332 | switch (air_tag) { |
| 7145 | .add => .{ .v_ps, .add }, | 7333 | .add => .{ .v_ps, .add }, |
| 7146 | .sub => .{ .v_ps, .sub }, | 7334 | .sub => .{ .v_ps, .sub }, |
| 7147 | .mul => .{ .v_ps, .mul }, | 7335 | .mul => .{ .v_ps, .mul }, |
| 7148 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 7336 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 7149 | .max => .{ .v_ps, .max }, | 7337 | .max => .{ .v_ps, .max }, |
| 7150 | .min => .{ .v_ps, .max }, | 7338 | .min => .{ .v_ps, .max }, |
| 7151 | else => unreachable, | 7339 | else => unreachable, |
| 7152 | }, | 7340 | }, |
| 7153 | dst_reg.to256(), | 7341 | dst_reg.to256(), |
| 7154 | dst_reg.to256(), | 7342 | dst_reg.to256(), |
| 7155 | tmp_reg, | 7343 | tmp_reg, |
| 7156 | ); | 7344 | ); |
| 7157 | try self.asmRegisterRegisterImmediate( | 7345 | try self.asmRegisterRegisterImmediate( |
| 7158 | .{ .v_, .cvtps2ph }, | 7346 | .{ .v_, .cvtps2ph }, |
| 7159 | dst_reg, | 7347 | dst_reg, |
| 7160 | dst_reg.to256(), | 7348 | dst_reg.to256(), |
| 7161 | Immediate.u(0b1_00), | 7349 | Immediate.u(0b1_00), |
| 7162 | ); | 7350 | ); |
| 7163 | return dst_mcv; | 7351 | return dst_mcv; |
| 7164 | }, | 7352 | }, |
| 7165 | else => null, | 7353 | else => break :tag null, |
| 7166 | } else null, | 7354 | } |
| 7355 | }, | ||
| 7167 | 32 => switch (lhs_ty.vectorLen(mod)) { | 7356 | 32 => switch (lhs_ty.vectorLen(mod)) { |
| 7168 | 1 => switch (air_tag) { | 7357 | 1 => switch (air_tag) { |
| 7169 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, | 7358 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, |
| ... | @@ -7290,18 +7479,16 @@ fn genBinOp( | ... | @@ -7290,18 +7479,16 @@ fn genBinOp( |
| 7290 | 7479 | ||
| 7291 | switch (air_tag) { | 7480 | switch (air_tag) { |
| 7292 | .add, .add_wrap, .sub, .sub_wrap, .mul, .mul_wrap, .div_float, .div_exact => {}, | 7481 | .add, .add_wrap, .sub, .sub_wrap, .mul, .mul_wrap, .div_float, .div_exact => {}, |
| 7293 | .div_trunc, .div_floor => if (self.hasFeature(.sse4_1)) try self.genRound( | 7482 | .div_trunc, .div_floor => try self.genRound( |
| 7294 | lhs_ty, | 7483 | lhs_ty, |
| 7295 | dst_reg, | 7484 | dst_reg, |
| 7296 | .{ .register = dst_reg }, | 7485 | .{ .register = dst_reg }, |
| 7297 | switch (air_tag) { | 7486 | .{ .mode = switch (air_tag) { |
| 7298 | .div_trunc => 0b1_0_11, | 7487 | .div_trunc => .zero, |
| 7299 | .div_floor => 0b1_0_01, | 7488 | .div_floor => .down, |
| 7300 | else => unreachable, | 7489 | else => unreachable, |
| 7301 | }, | 7490 | }, .precision = .inexact }, |
| 7302 | ) else return self.fail("TODO implement genBinOp for {s} {} without sse4_1 feature", .{ | 7491 | ), |
| 7303 | @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?), | ||
| 7304 | }), | ||
| 7305 | .bit_and, .bit_or, .xor => {}, | 7492 | .bit_and, .bit_or, .xor => {}, |
| 7306 | .max, .min => if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx)) { | 7493 | .max, .min => if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx)) { |
| 7307 | const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size); | 7494 | const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size); |
| ... | @@ -7558,6 +7745,7 @@ fn genBinOpMir( | ... | @@ -7558,6 +7745,7 @@ fn genBinOpMir( |
| 7558 | .lea_tlv, | 7745 | .lea_tlv, |
| 7559 | .lea_frame, | 7746 | .lea_frame, |
| 7560 | .reserved_frame, | 7747 | .reserved_frame, |
| 7748 | .air_ref, | ||
| 7561 | => unreachable, // unmodifiable destination | 7749 | => unreachable, // unmodifiable destination |
| 7562 | .register, .register_offset => { | 7750 | .register, .register_offset => { |
| 7563 | assert(dst_mcv.isRegister()); | 7751 | assert(dst_mcv.isRegister()); |
| ... | @@ -7673,6 +7861,7 @@ fn genBinOpMir( | ... | @@ -7673,6 +7861,7 @@ fn genBinOpMir( |
| 7673 | else => unreachable, | 7861 | else => unreachable, |
| 7674 | } | 7862 | } |
| 7675 | }, | 7863 | }, |
| 7864 | .air_ref => |ref| try self.genBinOpMir(mir_tag, ty, dst_mcv, try self.resolveInst(ref)), | ||
| 7676 | } | 7865 | } |
| 7677 | }, | 7866 | }, |
| 7678 | .memory, .indirect, .load_got, .load_direct, .load_tlv, .load_frame => { | 7867 | .memory, .indirect, .load_got, .load_direct, .load_tlv, .load_frame => { |
| ... | @@ -7696,13 +7885,18 @@ fn genBinOpMir( | ... | @@ -7696,13 +7885,18 @@ fn genBinOpMir( |
| 7696 | }; | 7885 | }; |
| 7697 | defer if (dst_info) |info| self.register_manager.unlockReg(info.addr_lock); | 7886 | defer if (dst_info) |info| self.register_manager.unlockReg(info.addr_lock); |
| 7698 | 7887 | ||
| 7699 | const src_info: OpInfo = switch (src_mcv) { | 7888 | const resolved_src_mcv = switch (src_mcv) { |
| 7889 | else => src_mcv, | ||
| 7890 | .air_ref => |ref| try self.resolveInst(ref), | ||
| 7891 | }; | ||
| 7892 | const src_info: OpInfo = switch (resolved_src_mcv) { | ||
| 7700 | .none, | 7893 | .none, |
| 7701 | .unreach, | 7894 | .unreach, |
| 7702 | .dead, | 7895 | .dead, |
| 7703 | .undef, | 7896 | .undef, |
| 7704 | .register_overflow, | 7897 | .register_overflow, |
| 7705 | .reserved_frame, | 7898 | .reserved_frame, |
| 7899 | .air_ref, | ||
| 7706 | => unreachable, | 7900 | => unreachable, |
| 7707 | .immediate, | 7901 | .immediate, |
| 7708 | .register, | 7902 | .register, |
| ... | @@ -7716,7 +7910,7 @@ fn genBinOpMir( | ... | @@ -7716,7 +7910,7 @@ fn genBinOpMir( |
| 7716 | .lea_frame, | 7910 | .lea_frame, |
| 7717 | => null, | 7911 | => null, |
| 7718 | .memory, .load_got, .load_direct, .load_tlv => src: { | 7912 | .memory, .load_got, .load_direct, .load_tlv => src: { |
| 7719 | switch (src_mcv) { | 7913 | switch (resolved_src_mcv) { |
| 7720 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and | 7914 | .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and |
| 7721 | math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null) | 7915 | math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null) |
| 7722 | break :src null, | 7916 | break :src null, |
| ... | @@ -7728,7 +7922,7 @@ fn genBinOpMir( | ... | @@ -7728,7 +7922,7 @@ fn genBinOpMir( |
| 7728 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 7922 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 7729 | errdefer self.register_manager.unlockReg(src_addr_lock); | 7923 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 7730 | 7924 | ||
| 7731 | try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address()); | 7925 | try self.genSetReg(src_addr_reg, Type.usize, resolved_src_mcv.address()); |
| 7732 | break :src .{ | 7926 | break :src .{ |
| 7733 | .addr_reg = src_addr_reg, | 7927 | .addr_reg = src_addr_reg, |
| 7734 | .addr_lock = src_addr_lock, | 7928 | .addr_lock = src_addr_lock, |
| ... | @@ -7775,13 +7969,14 @@ fn genBinOpMir( | ... | @@ -7775,13 +7969,14 @@ fn genBinOpMir( |
| 7775 | else => unreachable, | 7969 | else => unreachable, |
| 7776 | }, | 7970 | }, |
| 7777 | ); | 7971 | ); |
| 7778 | switch (src_mcv) { | 7972 | switch (resolved_src_mcv) { |
| 7779 | .none, | 7973 | .none, |
| 7780 | .unreach, | 7974 | .unreach, |
| 7781 | .dead, | 7975 | .dead, |
| 7782 | .undef, | 7976 | .undef, |
| 7783 | .register_overflow, | 7977 | .register_overflow, |
| 7784 | .reserved_frame, | 7978 | .reserved_frame, |
| 7979 | .air_ref, | ||
| 7785 | => unreachable, | 7980 | => unreachable, |
| 7786 | .register => |src_reg| switch (off) { | 7981 | .register => |src_reg| switch (off) { |
| 7787 | 0 => try self.asmMemoryRegister( | 7982 | 0 => try self.asmMemoryRegister( |
| ... | @@ -7857,7 +8052,7 @@ fn genBinOpMir( | ... | @@ -7857,7 +8052,7 @@ fn genBinOpMir( |
| 7857 | => { | 8052 | => { |
| 7858 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, if (src_info) |info| .{ | 8053 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, if (src_info) |info| .{ |
| 7859 | .indirect = .{ .reg = info.addr_reg, .off = off }, | 8054 | .indirect = .{ .reg = info.addr_reg, .off = off }, |
| 7860 | } else switch (src_mcv) { | 8055 | } else switch (resolved_src_mcv) { |
| 7861 | .eflags, | 8056 | .eflags, |
| 7862 | .register_offset, | 8057 | .register_offset, |
| 7863 | .lea_direct, | 8058 | .lea_direct, |
| ... | @@ -7865,7 +8060,7 @@ fn genBinOpMir( | ... | @@ -7865,7 +8060,7 @@ fn genBinOpMir( |
| 7865 | .lea_tlv, | 8060 | .lea_tlv, |
| 7866 | .lea_frame, | 8061 | .lea_frame, |
| 7867 | => switch (off) { | 8062 | => switch (off) { |
| 7868 | 0 => src_mcv, | 8063 | 0 => resolved_src_mcv, |
| 7869 | else => .{ .immediate = 0 }, | 8064 | else => .{ .immediate = 0 }, |
| 7870 | }, | 8065 | }, |
| 7871 | .memory => |addr| .{ .memory = @bitCast(@as(i64, @bitCast(addr)) + off) }, | 8066 | .memory => |addr| .{ .memory = @bitCast(@as(i64, @bitCast(addr)) + off) }, |
| ... | @@ -7910,19 +8105,25 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -7910,19 +8105,25 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 7910 | .lea_tlv, | 8105 | .lea_tlv, |
| 7911 | .lea_frame, | 8106 | .lea_frame, |
| 7912 | .reserved_frame, | 8107 | .reserved_frame, |
| 8108 | .air_ref, | ||
| 7913 | => unreachable, // unmodifiable destination | 8109 | => unreachable, // unmodifiable destination |
| 7914 | .register => |dst_reg| { | 8110 | .register => |dst_reg| { |
| 7915 | const dst_alias = registerAlias(dst_reg, abi_size); | 8111 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 7916 | const dst_lock = self.register_manager.lockReg(dst_reg); | 8112 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 7917 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 8113 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 7918 | 8114 | ||
| 7919 | switch (src_mcv) { | 8115 | const resolved_src_mcv = switch (src_mcv) { |
| 8116 | else => src_mcv, | ||
| 8117 | .air_ref => |ref| try self.resolveInst(ref), | ||
| 8118 | }; | ||
| 8119 | switch (resolved_src_mcv) { | ||
| 7920 | .none, | 8120 | .none, |
| 7921 | .unreach, | 8121 | .unreach, |
| 7922 | .dead, | 8122 | .dead, |
| 7923 | .undef, | 8123 | .undef, |
| 7924 | .register_overflow, | 8124 | .register_overflow, |
| 7925 | .reserved_frame, | 8125 | .reserved_frame, |
| 8126 | .air_ref, | ||
| 7926 | => unreachable, | 8127 | => unreachable, |
| 7927 | .register => |src_reg| try self.asmRegisterRegister( | 8128 | .register => |src_reg| try self.asmRegisterRegister( |
| 7928 | .{ .i_, .mul }, | 8129 | .{ .i_, .mul }, |
| ... | @@ -7938,7 +8139,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -7938,7 +8139,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 7938 | Immediate.s(small), | 8139 | Immediate.s(small), |
| 7939 | ); | 8140 | ); |
| 7940 | } else { | 8141 | } else { |
| 7941 | const src_reg = try self.copyToTmpRegister(dst_ty, src_mcv); | 8142 | const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv); |
| 7942 | return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg }); | 8143 | return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg }); |
| 7943 | } | 8144 | } |
| 7944 | }, | 8145 | }, |
| ... | @@ -7954,19 +8155,22 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -7954,19 +8155,22 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 7954 | => try self.asmRegisterRegister( | 8155 | => try self.asmRegisterRegister( |
| 7955 | .{ .i_, .mul }, | 8156 | .{ .i_, .mul }, |
| 7956 | dst_alias, | 8157 | dst_alias, |
| 7957 | registerAlias(try self.copyToTmpRegister(dst_ty, src_mcv), abi_size), | 8158 | registerAlias(try self.copyToTmpRegister(dst_ty, resolved_src_mcv), abi_size), |
| 7958 | ), | 8159 | ), |
| 7959 | .memory, .indirect, .load_frame => try self.asmRegisterMemory( | 8160 | .memory, .indirect, .load_frame => try self.asmRegisterMemory( |
| 7960 | .{ .i_, .mul }, | 8161 | .{ .i_, .mul }, |
| 7961 | dst_alias, | 8162 | dst_alias, |
| 7962 | Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { | 8163 | Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (resolved_src_mcv) { |
| 7963 | .memory => |addr| .{ | 8164 | .memory => |addr| .{ |
| 7964 | .base = .{ .reg = .ds }, | 8165 | .base = .{ .reg = .ds }, |
| 7965 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse | 8166 | .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| 7966 | return self.asmRegisterRegister( | 8167 | return self.asmRegisterRegister( |
| 7967 | .{ .i_, .mul }, | 8168 | .{ .i_, .mul }, |
| 7968 | dst_alias, | 8169 | dst_alias, |
| 7969 | registerAlias(try self.copyToTmpRegister(dst_ty, src_mcv), abi_size), | 8170 | registerAlias( |
| 8171 | try self.copyToTmpRegister(dst_ty, resolved_src_mcv), | ||
| 8172 | abi_size, | ||
| 8173 | ), | ||
| 7970 | ), | 8174 | ), |
| 7971 | }, | 8175 | }, |
| 7972 | .indirect => |reg_off| .{ | 8176 | .indirect => |reg_off| .{ |
| ... | @@ -8124,31 +8328,85 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8124,31 +8328,85 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void { |
| 8124 | } | 8328 | } |
| 8125 | 8329 | ||
| 8126 | fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void { | 8330 | fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void { |
| 8127 | const mod = self.bin_file.options.module.?; | ||
| 8128 | if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{}); | 8331 | if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{}); |
| 8332 | |||
| 8129 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8333 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 8130 | const callee = pl_op.operand; | ||
| 8131 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 8334 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 8132 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); | 8335 | const arg_refs: []const Air.Inst.Ref = |
| 8133 | const ty = self.typeOf(callee); | 8336 | @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 8134 | 8337 | ||
| 8135 | const fn_ty = switch (ty.zigTypeTag(mod)) { | 8338 | const ExpectedContents = extern struct { |
| 8136 | .Fn => ty, | 8339 | tys: [16][@sizeOf(Type)]u8 align(@alignOf(Type)), |
| 8137 | .Pointer => ty.childType(mod), | 8340 | vals: [16][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)), |
| 8138 | else => unreachable, | ||
| 8139 | }; | 8341 | }; |
| 8342 | var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) = | ||
| 8343 | std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); | ||
| 8344 | const allocator = stack.get(); | ||
| 8345 | |||
| 8346 | const arg_tys = try allocator.alloc(Type, arg_refs.len); | ||
| 8347 | defer allocator.free(arg_tys); | ||
| 8348 | for (arg_tys, arg_refs) |*arg_ty, arg_ref| arg_ty.* = self.typeOf(arg_ref); | ||
| 8349 | |||
| 8350 | const arg_vals = try allocator.alloc(MCValue, arg_refs.len); | ||
| 8351 | defer allocator.free(arg_vals); | ||
| 8352 | for (arg_vals, arg_refs) |*arg_val, arg_ref| arg_val.* = .{ .air_ref = arg_ref }; | ||
| 8353 | |||
| 8354 | const ret = try self.genCall(.{ .air = pl_op.operand }, arg_tys, arg_vals); | ||
| 8355 | |||
| 8356 | var bt = self.liveness.iterateBigTomb(inst); | ||
| 8357 | self.feed(&bt, pl_op.operand); | ||
| 8358 | for (arg_refs) |arg_ref| self.feed(&bt, arg_ref); | ||
| 8140 | 8359 | ||
| 8360 | const result = if (self.liveness.isUnused(inst)) .unreach else ret; | ||
| 8361 | return self.finishAirResult(inst, result); | ||
| 8362 | } | ||
| 8363 | |||
| 8364 | fn genCall(self: *Self, info: union(enum) { | ||
| 8365 | air: Air.Inst.Ref, | ||
| 8366 | lib: struct { | ||
| 8367 | return_type: InternPool.Index, | ||
| 8368 | param_types: []const InternPool.Index, | ||
| 8369 | lib: ?[]const u8 = null, | ||
| 8370 | callee: []const u8, | ||
| 8371 | }, | ||
| 8372 | }, arg_types: []const Type, args: []const MCValue) !MCValue { | ||
| 8373 | const mod = self.bin_file.options.module.?; | ||
| 8374 | |||
| 8375 | const fn_ty = switch (info) { | ||
| 8376 | .air => |callee| fn_info: { | ||
| 8377 | const callee_ty = self.typeOf(callee); | ||
| 8378 | break :fn_info switch (callee_ty.zigTypeTag(mod)) { | ||
| 8379 | .Fn => callee_ty, | ||
| 8380 | .Pointer => callee_ty.childType(mod), | ||
| 8381 | else => unreachable, | ||
| 8382 | }; | ||
| 8383 | }, | ||
| 8384 | .lib => |lib| try mod.funcType(.{ | ||
| 8385 | .param_types = lib.param_types, | ||
| 8386 | .return_type = lib.return_type, | ||
| 8387 | .cc = .C, | ||
| 8388 | }), | ||
| 8389 | }; | ||
| 8141 | const fn_info = mod.typeToFunc(fn_ty).?; | 8390 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 8142 | 8391 | ||
| 8143 | var info = try self.resolveCallingConventionValues(fn_info, args[fn_info.param_types.len..], .call_frame); | 8392 | const ExpectedContents = [16]Type; |
| 8144 | defer info.deinit(self); | 8393 | var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) = |
| 8394 | std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); | ||
| 8395 | const allocator = stack.get(); | ||
| 8396 | |||
| 8397 | const var_args = try allocator.alloc(Type, args.len - fn_info.param_types.len); | ||
| 8398 | defer allocator.free(var_args); | ||
| 8399 | for (var_args, arg_types[fn_info.param_types.len..]) |*var_arg, arg_ty| var_arg.* = arg_ty; | ||
| 8400 | |||
| 8401 | var call_info = | ||
| 8402 | try self.resolveCallingConventionValues(fn_info, var_args, .call_frame); | ||
| 8403 | defer call_info.deinit(self); | ||
| 8145 | 8404 | ||
| 8146 | // We need a properly aligned and sized call frame to be able to call this function. | 8405 | // We need a properly aligned and sized call frame to be able to call this function. |
| 8147 | { | 8406 | { |
| 8148 | const needed_call_frame = | 8407 | const needed_call_frame = FrameAlloc.init(.{ |
| 8149 | FrameAlloc.init(.{ | 8408 | .size = call_info.stack_byte_count, |
| 8150 | .size = info.stack_byte_count, | 8409 | .alignment = call_info.stack_align, |
| 8151 | .alignment = info.stack_align, | ||
| 8152 | }); | 8410 | }); |
| 8153 | const frame_allocs_slice = self.frame_allocs.slice(); | 8411 | const frame_allocs_slice = self.frame_allocs.slice(); |
| 8154 | const stack_frame_size = | 8412 | const stack_frame_size = |
| ... | @@ -8164,24 +8422,20 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -8164,24 +8422,20 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 8164 | 8422 | ||
| 8165 | // set stack arguments first because this can clobber registers | 8423 | // set stack arguments first because this can clobber registers |
| 8166 | // also clobber spill arguments as we go | 8424 | // also clobber spill arguments as we go |
| 8167 | switch (info.return_value.long) { | 8425 | switch (call_info.return_value.long) { |
| 8168 | .none, .unreach => {}, | 8426 | .none, .unreach => {}, |
| 8169 | .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}), | 8427 | .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}), |
| 8170 | else => unreachable, | 8428 | else => unreachable, |
| 8171 | } | 8429 | } |
| 8172 | for (args, info.args) |arg, mc_arg| { | 8430 | for (call_info.args, arg_types, args) |dst_arg, arg_ty, src_arg| switch (dst_arg) { |
| 8173 | const arg_ty = self.typeOf(arg); | 8431 | .none => {}, |
| 8174 | const arg_mcv = try self.resolveInst(arg); | 8432 | .register => |reg| try self.spillRegisters(&.{reg}), |
| 8175 | switch (mc_arg) { | 8433 | .load_frame => try self.genCopy(arg_ty, dst_arg, src_arg), |
| 8176 | .none => {}, | 8434 | else => unreachable, |
| 8177 | .register => |reg| try self.spillRegisters(&.{reg}), | 8435 | }; |
| 8178 | .load_frame => try self.genCopy(arg_ty, mc_arg, arg_mcv), | ||
| 8179 | else => unreachable, | ||
| 8180 | } | ||
| 8181 | } | ||
| 8182 | 8436 | ||
| 8183 | // now we are free to set register arguments | 8437 | // now we are free to set register arguments |
| 8184 | const ret_lock = switch (info.return_value.long) { | 8438 | const ret_lock = switch (call_info.return_value.long) { |
| 8185 | .none, .unreach => null, | 8439 | .none, .unreach => null, |
| 8186 | .indirect => |reg_off| lock: { | 8440 | .indirect => |reg_off| lock: { |
| 8187 | const ret_ty = fn_info.return_type.toType(); | 8441 | const ret_ty = fn_info.return_type.toType(); |
| ... | @@ -8189,125 +8443,80 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -8189,125 +8443,80 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 8189 | try self.genSetReg(reg_off.reg, Type.usize, .{ | 8443 | try self.genSetReg(reg_off.reg, Type.usize, .{ |
| 8190 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, | 8444 | .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, |
| 8191 | }); | 8445 | }); |
| 8192 | info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; | 8446 | call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; |
| 8193 | break :lock self.register_manager.lockRegAssumeUnused(reg_off.reg); | 8447 | break :lock self.register_manager.lockRegAssumeUnused(reg_off.reg); |
| 8194 | }, | 8448 | }, |
| 8195 | else => unreachable, | 8449 | else => unreachable, |
| 8196 | }; | 8450 | }; |
| 8197 | defer if (ret_lock) |lock| self.register_manager.unlockReg(lock); | 8451 | defer if (ret_lock) |lock| self.register_manager.unlockReg(lock); |
| 8198 | 8452 | ||
| 8199 | for (args, info.args) |arg, mc_arg| { | 8453 | for (call_info.args, arg_types, args) |dst_arg, arg_ty, src_arg| { |
| 8200 | const arg_ty = self.typeOf(arg); | 8454 | switch (dst_arg) { |
| 8201 | const arg_mcv = try self.resolveInst(arg); | ||
| 8202 | switch (mc_arg) { | ||
| 8203 | .none, .load_frame => {}, | 8455 | .none, .load_frame => {}, |
| 8204 | .register => try self.genCopy(arg_ty, mc_arg, arg_mcv), | 8456 | .register => try self.genCopy(arg_ty, dst_arg, src_arg), |
| 8205 | else => unreachable, | 8457 | else => unreachable, |
| 8206 | } | 8458 | } |
| 8207 | } | 8459 | } |
| 8208 | 8460 | ||
| 8209 | // Due to incremental compilation, how function calls are generated depends | 8461 | // Due to incremental compilation, how function calls are generated depends |
| 8210 | // on linking. | 8462 | // on linking. |
| 8211 | if (try self.air.value(callee, mod)) |func_value| { | 8463 | switch (info) { |
| 8212 | const func_key = mod.intern_pool.indexToKey(func_value.ip_index); | 8464 | .air => |callee| if (try self.air.value(callee, mod)) |func_value| { |
| 8213 | if (switch (func_key) { | 8465 | const func_key = mod.intern_pool.indexToKey(func_value.ip_index); |
| 8214 | .func => |func| func.owner_decl, | 8466 | if (switch (func_key) { |
| 8215 | .ptr => |ptr| switch (ptr.addr) { | 8467 | .func => |func| func.owner_decl, |
| 8216 | .decl => |decl| decl, | 8468 | .ptr => |ptr| switch (ptr.addr) { |
| 8469 | .decl => |decl| decl, | ||
| 8470 | else => null, | ||
| 8471 | }, | ||
| 8217 | else => null, | 8472 | else => null, |
| 8218 | }, | 8473 | }) |owner_decl| { |
| 8219 | else => null, | 8474 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 8220 | }) |owner_decl| { | 8475 | const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl); |
| 8221 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 8476 | const sym = elf_file.symbol(sym_index); |
| 8222 | const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl); | 8477 | sym.flags.needs_got = true; |
| 8223 | const sym = elf_file.symbol(sym_index); | 8478 | _ = try sym.getOrCreateGotEntry(sym_index, elf_file); |
| 8224 | sym.flags.needs_got = true; | 8479 | _ = try self.addInst(.{ |
| 8225 | _ = try sym.getOrCreateGotEntry(sym_index, elf_file); | 8480 | .tag = .call, |
| 8226 | _ = try self.addInst(.{ | 8481 | .ops = .direct_got_reloc, |
| 8227 | .tag = .call, | 8482 | .data = .{ .reloc = .{ |
| 8228 | .ops = .direct_got_reloc, | 8483 | .atom_index = try self.owner.getSymbolIndex(self), |
| 8229 | .data = .{ .reloc = .{ | 8484 | .sym_index = sym.esym_index, |
| 8230 | .atom_index = try self.owner.getSymbolIndex(self), | 8485 | } }, |
| 8231 | .sym_index = sym.esym_index, | 8486 | }); |
| 8232 | } }, | 8487 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 8233 | }); | 8488 | const atom = try coff_file.getOrCreateAtomForDecl(owner_decl); |
| 8234 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 8489 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| 8235 | const atom = try coff_file.getOrCreateAtomForDecl(owner_decl); | 8490 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 8236 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 8491 | try self.asmRegister(.{ ._, .call }, .rax); |
| 8237 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 8492 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 8238 | try self.asmRegister(.{ ._, .call }, .rax); | 8493 | const atom = try macho_file.getOrCreateAtomForDecl(owner_decl); |
| 8239 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 8494 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; |
| 8240 | const atom = try macho_file.getOrCreateAtomForDecl(owner_decl); | 8495 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 8241 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; | 8496 | try self.asmRegister(.{ ._, .call }, .rax); |
| 8242 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 8497 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 8243 | try self.asmRegister(.{ ._, .call }, .rax); | 8498 | const atom_index = try p9.seeDecl(owner_decl); |
| 8244 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 8499 | const atom = p9.getAtom(atom_index); |
| 8245 | const atom_index = try p9.seeDecl(owner_decl); | 8500 | try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ |
| 8246 | const atom = p9.getAtom(atom_index); | 8501 | .base = .{ .reg = .ds }, |
| 8247 | try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{ | 8502 | .disp = @intCast(atom.getOffsetTableAddress(p9)), |
| 8248 | .base = .{ .reg = .ds }, | 8503 | })); |
| 8249 | .disp = @intCast(atom.getOffsetTableAddress(p9)), | 8504 | } else unreachable; |
| 8250 | })); | 8505 | } else if (func_value.getExternFunc(mod)) |extern_func| { |
| 8251 | } else unreachable; | 8506 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); |
| 8252 | } else if (func_value.getExternFunc(mod)) |extern_func| { | 8507 | const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name); |
| 8253 | const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name); | 8508 | try self.genExternSymbolRef(.call, lib_name, decl_name); |
| 8254 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); | ||
| 8255 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | ||
| 8256 | const atom_index = try self.owner.getSymbolIndex(self); | ||
| 8257 | const sym_index = try elf_file.getGlobalSymbol(decl_name, lib_name); | ||
| 8258 | _ = try self.addInst(.{ | ||
| 8259 | .tag = .call, | ||
| 8260 | .ops = .extern_fn_reloc, | ||
| 8261 | .data = .{ .reloc = .{ | ||
| 8262 | .atom_index = atom_index, | ||
| 8263 | .sym_index = sym_index, | ||
| 8264 | } }, | ||
| 8265 | }); | ||
| 8266 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | ||
| 8267 | const atom_index = try self.owner.getSymbolIndex(self); | ||
| 8268 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); | ||
| 8269 | _ = try self.addInst(.{ | ||
| 8270 | .tag = .mov, | ||
| 8271 | .ops = .import_reloc, | ||
| 8272 | .data = .{ .rx = .{ | ||
| 8273 | .r1 = .rax, | ||
| 8274 | .payload = try self.addExtra(Mir.Reloc{ | ||
| 8275 | .atom_index = atom_index, | ||
| 8276 | .sym_index = sym_index, | ||
| 8277 | }), | ||
| 8278 | } }, | ||
| 8279 | }); | ||
| 8280 | try self.asmRegister(.{ ._, .call }, .rax); | ||
| 8281 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | ||
| 8282 | const atom_index = try self.owner.getSymbolIndex(self); | ||
| 8283 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); | ||
| 8284 | _ = try self.addInst(.{ | ||
| 8285 | .tag = .call, | ||
| 8286 | .ops = .extern_fn_reloc, | ||
| 8287 | .data = .{ .reloc = .{ | ||
| 8288 | .atom_index = atom_index, | ||
| 8289 | .sym_index = sym_index, | ||
| 8290 | } }, | ||
| 8291 | }); | ||
| 8292 | } else { | 8509 | } else { |
| 8293 | return self.fail("TODO implement calling extern functions", .{}); | 8510 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 8294 | } | 8511 | } |
| 8295 | } else { | 8512 | } else { |
| 8296 | return self.fail("TODO implement calling bitcasted functions", .{}); | 8513 | assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer); |
| 8297 | } | 8514 | try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }); |
| 8298 | } else { | 8515 | try self.asmRegister(.{ ._, .call }, .rax); |
| 8299 | assert(ty.zigTypeTag(mod) == .Pointer); | 8516 | }, |
| 8300 | const mcv = try self.resolveInst(callee); | 8517 | .lib => |lib| try self.genExternSymbolRef(.call, lib.lib, lib.callee), |
| 8301 | try self.genSetReg(.rax, Type.usize, mcv); | ||
| 8302 | try self.asmRegister(.{ ._, .call }, .rax); | ||
| 8303 | } | 8518 | } |
| 8304 | 8519 | return call_info.return_value.short; | |
| 8305 | var bt = self.liveness.iterateBigTomb(inst); | ||
| 8306 | self.feed(&bt, callee); | ||
| 8307 | for (args) |arg| self.feed(&bt, arg); | ||
| 8308 | |||
| 8309 | const result = if (self.liveness.isUnused(inst)) .unreach else info.return_value.short; | ||
| 8310 | return self.finishAirResult(inst, result); | ||
| 8311 | } | 8520 | } |
| 8312 | 8521 | ||
| 8313 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { | 8522 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -8357,26 +8566,64 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -8357,26 +8566,64 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 8357 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 8566 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 8358 | const ty = self.typeOf(bin_op.lhs); | 8567 | const ty = self.typeOf(bin_op.lhs); |
| 8359 | 8568 | ||
| 8360 | try self.spillEflagsIfOccupied(); | 8569 | const result: Condition = result: { |
| 8361 | self.eflags_inst = inst; | 8570 | switch (ty.zigTypeTag(mod)) { |
| 8571 | .Float => { | ||
| 8572 | const float_bits = ty.floatBits(self.target.*); | ||
| 8573 | if (switch (float_bits) { | ||
| 8574 | 16 => !self.hasFeature(.f16c), | ||
| 8575 | 32, 64 => false, | ||
| 8576 | 80, 128 => true, | ||
| 8577 | else => unreachable, | ||
| 8578 | }) { | ||
| 8579 | var callee: ["__???f2".len]u8 = undefined; | ||
| 8580 | const ret = try self.genCall(.{ .lib = .{ | ||
| 8581 | .return_type = .i32_type, | ||
| 8582 | .param_types = &.{ ty.toIntern(), ty.toIntern() }, | ||
| 8583 | .callee = std.fmt.bufPrint(&callee, "__{s}{c}f2", .{ | ||
| 8584 | switch (op) { | ||
| 8585 | .eq => "eq", | ||
| 8586 | .neq => "ne", | ||
| 8587 | .lt => "lt", | ||
| 8588 | .lte => "le", | ||
| 8589 | .gt => "gt", | ||
| 8590 | .gte => "ge", | ||
| 8591 | }, | ||
| 8592 | floatCompilerRtAbiName(float_bits), | ||
| 8593 | }) catch unreachable, | ||
| 8594 | } }, &.{ ty, ty }, &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }); | ||
| 8595 | try self.genBinOpMir(.{ ._, .@"test" }, Type.i32, ret, ret); | ||
| 8596 | break :result switch (op) { | ||
| 8597 | .eq => .e, | ||
| 8598 | .neq => .ne, | ||
| 8599 | .lt => .l, | ||
| 8600 | .lte => .le, | ||
| 8601 | .gt => .g, | ||
| 8602 | .gte => .ge, | ||
| 8603 | }; | ||
| 8604 | } | ||
| 8605 | }, | ||
| 8606 | else => {}, | ||
| 8607 | } | ||
| 8362 | 8608 | ||
| 8363 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 8609 | try self.spillEflagsIfOccupied(); |
| 8364 | const lhs_lock = switch (lhs_mcv) { | ||
| 8365 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | ||
| 8366 | else => null, | ||
| 8367 | }; | ||
| 8368 | defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 8369 | 8610 | ||
| 8370 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | 8611 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 8371 | const rhs_lock = switch (rhs_mcv) { | 8612 | const lhs_lock = switch (lhs_mcv) { |
| 8372 | .register => |reg| self.register_manager.lockReg(reg), | 8613 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 8373 | else => null, | 8614 | else => null, |
| 8374 | }; | 8615 | }; |
| 8375 | defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); | 8616 | defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 8617 | |||
| 8618 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | ||
| 8619 | const rhs_lock = switch (rhs_mcv) { | ||
| 8620 | .register => |reg| self.register_manager.lockReg(reg), | ||
| 8621 | else => null, | ||
| 8622 | }; | ||
| 8623 | defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 8376 | 8624 | ||
| 8377 | const result = MCValue{ | 8625 | switch (ty.zigTypeTag(mod)) { |
| 8378 | .eflags = switch (ty.zigTypeTag(mod)) { | 8626 | else => { |
| 8379 | else => result: { | ||
| 8380 | const abi_size: u16 = @intCast(ty.abiSize(mod)); | 8627 | const abi_size: u16 = @intCast(ty.abiSize(mod)); |
| 8381 | const may_flip: enum { | 8628 | const may_flip: enum { |
| 8382 | may_flip, | 8629 | may_flip, |
| ... | @@ -8478,7 +8725,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -8478,7 +8725,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 8478 | }, | 8725 | }, |
| 8479 | ); | 8726 | ); |
| 8480 | }, | 8727 | }, |
| 8481 | .Float => result: { | 8728 | .Float => { |
| 8482 | const flipped = switch (op) { | 8729 | const flipped = switch (op) { |
| 8483 | .lt, .lte => true, | 8730 | .lt, .lte => true, |
| 8484 | .eq, .gte, .gt, .neq => false, | 8731 | .eq, .gte, .gt, .neq => false, |
| ... | @@ -8494,7 +8741,8 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -8494,7 +8741,8 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 8494 | const src_mcv = if (flipped) lhs_mcv else rhs_mcv; | 8741 | const src_mcv = if (flipped) lhs_mcv else rhs_mcv; |
| 8495 | 8742 | ||
| 8496 | switch (ty.floatBits(self.target.*)) { | 8743 | switch (ty.floatBits(self.target.*)) { |
| 8497 | 16 => if (self.hasFeature(.f16c)) { | 8744 | 16 => { |
| 8745 | assert(self.hasFeature(.f16c)); | ||
| 8498 | const tmp1_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 8746 | const tmp1_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 8499 | const tmp1_mcv = MCValue{ .register = tmp1_reg }; | 8747 | const tmp1_mcv = MCValue{ .register = tmp1_reg }; |
| 8500 | const tmp1_lock = self.register_manager.lockRegAssumeUnused(tmp1_reg); | 8748 | const tmp1_lock = self.register_manager.lockRegAssumeUnused(tmp1_reg); |
| ... | @@ -8523,9 +8771,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -8523,9 +8771,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 8523 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, tmp1_reg, tmp1_reg); | 8771 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, tmp1_reg, tmp1_reg); |
| 8524 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg); | 8772 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg); |
| 8525 | try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv); | 8773 | try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv); |
| 8526 | } else return self.fail("TODO implement airCmp for {}", .{ | 8774 | }, |
| 8527 | ty.fmt(mod), | ||
| 8528 | }), | ||
| 8529 | 32 => try self.genBinOpMir( | 8775 | 32 => try self.genBinOpMir( |
| 8530 | .{ ._ss, .ucomi }, | 8776 | .{ ._ss, .ucomi }, |
| 8531 | ty, | 8777 | ty, |
| ... | @@ -8538,9 +8784,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -8538,9 +8784,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 8538 | .{ .register = dst_reg }, | 8784 | .{ .register = dst_reg }, |
| 8539 | src_mcv, | 8785 | src_mcv, |
| 8540 | ), | 8786 | ), |
| 8541 | else => return self.fail("TODO implement airCmp for {}", .{ | 8787 | else => unreachable, |
| 8542 | ty.fmt(mod), | ||
| 8543 | }), | ||
| 8544 | } | 8788 | } |
| 8545 | 8789 | ||
| 8546 | break :result switch (if (flipped) op.reverse() else op) { | 8790 | break :result switch (if (flipped) op.reverse() else op) { |
| ... | @@ -8551,9 +8795,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -8551,9 +8795,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 8551 | .neq => .nz_or_p, | 8795 | .neq => .nz_or_p, |
| 8552 | }; | 8796 | }; |
| 8553 | }, | 8797 | }, |
| 8554 | }, | 8798 | } |
| 8555 | }; | 8799 | }; |
| 8556 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 8800 | |
| 8801 | self.eflags_inst = inst; | ||
| 8802 | return self.finishAir(inst, .{ .eflags = result }, .{ bin_op.lhs, bin_op.rhs, .none }); | ||
| 8557 | } | 8803 | } |
| 8558 | 8804 | ||
| 8559 | fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { | 8805 | fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -8571,7 +8817,6 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8571,7 +8817,6 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 8571 | try self.genLazySymbolRef(.lea, addr_reg, link.File.LazySymbol.initDecl(.const_data, null, mod)); | 8817 | try self.genLazySymbolRef(.lea, addr_reg, link.File.LazySymbol.initDecl(.const_data, null, mod)); |
| 8572 | 8818 | ||
| 8573 | try self.spillEflagsIfOccupied(); | 8819 | try self.spillEflagsIfOccupied(); |
| 8574 | self.eflags_inst = inst; | ||
| 8575 | 8820 | ||
| 8576 | const op_ty = self.typeOf(un_op); | 8821 | const op_ty = self.typeOf(un_op); |
| 8577 | const op_abi_size: u32 = @intCast(op_ty.abiSize(mod)); | 8822 | const op_abi_size: u32 = @intCast(op_ty.abiSize(mod)); |
| ... | @@ -8585,8 +8830,9 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8585,8 +8830,9 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 8585 | registerAlias(dst_reg, op_abi_size), | 8830 | registerAlias(dst_reg, op_abi_size), |
| 8586 | Memory.sib(Memory.PtrSize.fromSize(op_abi_size), .{ .base = .{ .reg = addr_reg } }), | 8831 | Memory.sib(Memory.PtrSize.fromSize(op_abi_size), .{ .base = .{ .reg = addr_reg } }), |
| 8587 | ); | 8832 | ); |
| 8588 | const result = MCValue{ .eflags = .b }; | 8833 | |
| 8589 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 8834 | self.eflags_inst = inst; |
| 8835 | return self.finishAir(inst, .{ .eflags = .b }, .{ un_op, .none, .none }); | ||
| 8590 | } | 8836 | } |
| 8591 | 8837 | ||
| 8592 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { | 8838 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -8776,7 +9022,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -8776,7 +9022,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 8776 | } | 9022 | } |
| 8777 | 9023 | ||
| 8778 | try self.spillEflagsIfOccupied(); | 9024 | try self.spillEflagsIfOccupied(); |
| 8779 | self.eflags_inst = inst; | ||
| 8780 | 9025 | ||
| 8781 | const pl_ty = opt_ty.optionalChild(mod); | 9026 | const pl_ty = opt_ty.optionalChild(mod); |
| 8782 | 9027 | ||
| ... | @@ -8785,6 +9030,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -8785,6 +9030,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 8785 | else | 9030 | else |
| 8786 | .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool }; | 9031 | .{ .off = @intCast(pl_ty.abiSize(mod)), .ty = Type.bool }; |
| 8787 | 9032 | ||
| 9033 | self.eflags_inst = inst; | ||
| 8788 | switch (opt_mcv) { | 9034 | switch (opt_mcv) { |
| 8789 | .none, | 9035 | .none, |
| 8790 | .unreach, | 9036 | .unreach, |
| ... | @@ -8799,6 +9045,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -8799,6 +9045,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 8799 | .lea_tlv, | 9045 | .lea_tlv, |
| 8800 | .lea_frame, | 9046 | .lea_frame, |
| 8801 | .reserved_frame, | 9047 | .reserved_frame, |
| 9048 | .air_ref, | ||
| 8802 | => unreachable, | 9049 | => unreachable, |
| 8803 | 9050 | ||
| 8804 | .register => |opt_reg| { | 9051 | .register => |opt_reg| { |
| ... | @@ -8866,7 +9113,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -8866,7 +9113,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 8866 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { | 9113 | fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue { |
| 8867 | const mod = self.bin_file.options.module.?; | 9114 | const mod = self.bin_file.options.module.?; |
| 8868 | try self.spillEflagsIfOccupied(); | 9115 | try self.spillEflagsIfOccupied(); |
| 8869 | self.eflags_inst = inst; | ||
| 8870 | 9116 | ||
| 8871 | const opt_ty = ptr_ty.childType(mod); | 9117 | const opt_ty = ptr_ty.childType(mod); |
| 8872 | const pl_ty = opt_ty.optionalChild(mod); | 9118 | const pl_ty = opt_ty.optionalChild(mod); |
| ... | @@ -8892,6 +9138,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -8892,6 +9138,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 8892 | }), | 9138 | }), |
| 8893 | Immediate.u(0), | 9139 | Immediate.u(0), |
| 8894 | ); | 9140 | ); |
| 9141 | |||
| 9142 | self.eflags_inst = inst; | ||
| 8895 | return .{ .eflags = .e }; | 9143 | return .{ .eflags = .e }; |
| 8896 | } | 9144 | } |
| 8897 | 9145 | ||
| ... | @@ -8904,9 +9152,6 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! | ... | @@ -8904,9 +9152,6 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! |
| 8904 | } | 9152 | } |
| 8905 | 9153 | ||
| 8906 | try self.spillEflagsIfOccupied(); | 9154 | try self.spillEflagsIfOccupied(); |
| 8907 | if (maybe_inst) |inst| { | ||
| 8908 | self.eflags_inst = inst; | ||
| 8909 | } | ||
| 8910 | 9155 | ||
| 8911 | const err_off = errUnionErrorOffset(ty.errorUnionPayload(mod), mod); | 9156 | const err_off = errUnionErrorOffset(ty.errorUnionPayload(mod), mod); |
| 8912 | switch (operand) { | 9157 | switch (operand) { |
| ... | @@ -8944,6 +9189,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! | ... | @@ -8944,6 +9189,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) ! |
| 8944 | else => return self.fail("TODO implement isErr for {}", .{operand}), | 9189 | else => return self.fail("TODO implement isErr for {}", .{operand}), |
| 8945 | } | 9190 | } |
| 8946 | 9191 | ||
| 9192 | if (maybe_inst) |inst| self.eflags_inst = inst; | ||
| 8947 | return MCValue{ .eflags = .a }; | 9193 | return MCValue{ .eflags = .a }; |
| 8948 | } | 9194 | } |
| 8949 | 9195 | ||
| ... | @@ -9825,6 +10071,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError | ... | @@ -9825,6 +10071,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 9825 | .lea_tlv, | 10071 | .lea_tlv, |
| 9826 | .lea_frame, | 10072 | .lea_frame, |
| 9827 | .reserved_frame, | 10073 | .reserved_frame, |
| 10074 | .air_ref, | ||
| 9828 | => unreachable, // unmodifiable destination | 10075 | => unreachable, // unmodifiable destination |
| 9829 | .register => |reg| try self.genSetReg(reg, ty, src_mcv), | 10076 | .register => |reg| try self.genSetReg(reg, ty, src_mcv), |
| 9830 | .register_offset => |dst_reg_off| try self.genSetReg(dst_reg_off.reg, ty, switch (src_mcv) { | 10077 | .register_offset => |dst_reg_off| try self.genSetReg(dst_reg_off.reg, ty, switch (src_mcv) { |
| ... | @@ -10150,6 +10397,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -10150,6 +10397,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 10150 | @tagName(self.bin_file.tag), | 10397 | @tagName(self.bin_file.tag), |
| 10151 | }); | 10398 | }); |
| 10152 | }, | 10399 | }, |
| 10400 | .air_ref => |ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(ref)), | ||
| 10153 | } | 10401 | } |
| 10154 | } | 10402 | } |
| 10155 | 10403 | ||
| ... | @@ -10262,6 +10510,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -10262,6 +10510,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 10262 | }, | 10510 | }, |
| 10263 | else => try self.genInlineMemcpy(dst_ptr_mcv, src_mcv.address(), .{ .immediate = abi_size }), | 10511 | else => try self.genInlineMemcpy(dst_ptr_mcv, src_mcv.address(), .{ .immediate = abi_size }), |
| 10264 | }, | 10512 | }, |
| 10513 | .air_ref => |ref| try self.genSetMem(base, disp, ty, try self.resolveInst(ref)), | ||
| 10265 | } | 10514 | } |
| 10266 | } | 10515 | } |
| 10267 | 10516 | ||
| ... | @@ -10281,6 +10530,51 @@ fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue) | ... | @@ -10281,6 +10530,51 @@ fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue) |
| 10281 | try self.asmOpOnly(.{ .@"rep _sb", .sto }); | 10530 | try self.asmOpOnly(.{ .@"rep _sb", .sto }); |
| 10282 | } | 10531 | } |
| 10283 | 10532 | ||
| 10533 | fn genExternSymbolRef( | ||
| 10534 | self: *Self, | ||
| 10535 | comptime tag: Mir.Inst.Tag, | ||
| 10536 | lib: ?[]const u8, | ||
| 10537 | callee: []const u8, | ||
| 10538 | ) InnerError!void { | ||
| 10539 | const atom_index = try self.owner.getSymbolIndex(self); | ||
| 10540 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | ||
| 10541 | _ = try self.addInst(.{ | ||
| 10542 | .tag = tag, | ||
| 10543 | .ops = .extern_fn_reloc, | ||
| 10544 | .data = .{ .reloc = .{ | ||
| 10545 | .atom_index = atom_index, | ||
| 10546 | .sym_index = try elf_file.getGlobalSymbol(callee, lib), | ||
| 10547 | } }, | ||
| 10548 | }); | ||
| 10549 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | ||
| 10550 | _ = try self.addInst(.{ | ||
| 10551 | .tag = .mov, | ||
| 10552 | .ops = .import_reloc, | ||
| 10553 | .data = .{ .rx = .{ | ||
| 10554 | .r1 = .rax, | ||
| 10555 | .payload = try self.addExtra(Mir.Reloc{ | ||
| 10556 | .atom_index = atom_index, | ||
| 10557 | .sym_index = try coff_file.getGlobalSymbol(callee, lib), | ||
| 10558 | }), | ||
| 10559 | } }, | ||
| 10560 | }); | ||
| 10561 | switch (tag) { | ||
| 10562 | .mov => {}, | ||
| 10563 | .call => try self.asmRegister(.{ ._, .call }, .rax), | ||
| 10564 | else => unreachable, | ||
| 10565 | } | ||
| 10566 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | ||
| 10567 | _ = try self.addInst(.{ | ||
| 10568 | .tag = .call, | ||
| 10569 | .ops = .extern_fn_reloc, | ||
| 10570 | .data = .{ .reloc = .{ | ||
| 10571 | .atom_index = atom_index, | ||
| 10572 | .sym_index = try macho_file.getGlobalSymbol(callee, lib), | ||
| 10573 | } }, | ||
| 10574 | }); | ||
| 10575 | } else return self.fail("TODO implement calling extern functions", .{}); | ||
| 10576 | } | ||
| 10577 | |||
| 10284 | fn genLazySymbolRef( | 10578 | fn genLazySymbolRef( |
| 10285 | self: *Self, | 10579 | self: *Self, |
| 10286 | comptime tag: Mir.Inst.Tag, | 10580 | comptime tag: Mir.Inst.Tag, |
| ... | @@ -10480,106 +10774,150 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10480,106 +10774,150 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 10480 | const mod = self.bin_file.options.module.?; | 10774 | const mod = self.bin_file.options.module.?; |
| 10481 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 10775 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 10482 | 10776 | ||
| 10777 | const dst_ty = self.typeOfIndex(inst); | ||
| 10778 | const dst_bits = dst_ty.floatBits(self.target.*); | ||
| 10779 | |||
| 10483 | const src_ty = self.typeOf(ty_op.operand); | 10780 | const src_ty = self.typeOf(ty_op.operand); |
| 10484 | const src_bits: u32 = @intCast(src_ty.bitSize(mod)); | 10781 | const src_bits: u32 = @intCast(src_ty.bitSize(mod)); |
| 10485 | const src_signedness = | 10782 | const src_signedness = |
| 10486 | if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; | 10783 | if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; |
| 10487 | const dst_ty = self.typeOfIndex(inst); | ||
| 10488 | |||
| 10489 | const src_size = math.divCeil(u32, @max(switch (src_signedness) { | 10784 | const src_size = math.divCeil(u32, @max(switch (src_signedness) { |
| 10490 | .signed => src_bits, | 10785 | .signed => src_bits, |
| 10491 | .unsigned => src_bits + 1, | 10786 | .unsigned => src_bits + 1, |
| 10492 | }, 32), 8) catch unreachable; | 10787 | }, 32), 8) catch unreachable; |
| 10493 | if (src_size > 8) return self.fail("TODO implement airFloatFromInt from {} to {}", .{ | ||
| 10494 | src_ty.fmt(mod), dst_ty.fmt(mod), | ||
| 10495 | }); | ||
| 10496 | 10788 | ||
| 10497 | const src_mcv = try self.resolveInst(ty_op.operand); | 10789 | const result = result: { |
| 10498 | const src_reg = if (src_mcv.isRegister()) | 10790 | if (switch (dst_bits) { |
| 10499 | src_mcv.getReg().? | 10791 | 16, 80, 128 => true, |
| 10500 | else | 10792 | 32, 64 => src_size > 8 and src_size < 16, |
| 10501 | try self.copyToTmpRegister(src_ty, src_mcv); | 10793 | else => unreachable, |
| 10502 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | 10794 | }) { |
| 10503 | defer self.register_manager.unlockReg(src_lock); | 10795 | var callee: ["__floatun?i?f".len]u8 = undefined; |
| 10796 | break :result try self.genCall(.{ .lib = .{ | ||
| 10797 | .return_type = dst_ty.toIntern(), | ||
| 10798 | .param_types = &.{src_ty.toIntern()}, | ||
| 10799 | .callee = std.fmt.bufPrint(&callee, "__float{s}{c}i{c}f", .{ | ||
| 10800 | switch (src_signedness) { | ||
| 10801 | .signed => "", | ||
| 10802 | .unsigned => "un", | ||
| 10803 | }, | ||
| 10804 | intCompilerRtAbiName(src_bits), | ||
| 10805 | floatCompilerRtAbiName(dst_bits), | ||
| 10806 | }) catch unreachable, | ||
| 10807 | } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}); | ||
| 10808 | } | ||
| 10504 | 10809 | ||
| 10505 | if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg); | 10810 | if (src_size > 8) return self.fail("TODO implement airFloatFromInt from {} to {}", .{ |
| 10811 | src_ty.fmt(mod), dst_ty.fmt(mod), | ||
| 10812 | }); | ||
| 10506 | 10813 | ||
| 10507 | const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty, mod)); | 10814 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 10508 | const dst_mcv = MCValue{ .register = dst_reg }; | 10815 | const src_reg = if (src_mcv.isRegister()) |
| 10509 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 10816 | src_mcv.getReg().? |
| 10510 | defer self.register_manager.unlockReg(dst_lock); | 10817 | else |
| 10818 | try self.copyToTmpRegister(src_ty, src_mcv); | ||
| 10819 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | ||
| 10820 | defer self.register_manager.unlockReg(src_lock); | ||
| 10511 | 10821 | ||
| 10512 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(mod)) { | 10822 | if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg); |
| 10513 | .Float => switch (dst_ty.floatBits(self.target.*)) { | ||
| 10514 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 }, | ||
| 10515 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 }, | ||
| 10516 | 16, 80, 128 => null, | ||
| 10517 | else => unreachable, | ||
| 10518 | }, | ||
| 10519 | else => null, | ||
| 10520 | }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{ | ||
| 10521 | src_ty.fmt(mod), dst_ty.fmt(mod), | ||
| 10522 | }); | ||
| 10523 | const dst_alias = dst_reg.to128(); | ||
| 10524 | const src_alias = registerAlias(src_reg, src_size); | ||
| 10525 | switch (mir_tag[0]) { | ||
| 10526 | .v_ss, .v_sd => try self.asmRegisterRegisterRegister(mir_tag, dst_alias, dst_alias, src_alias), | ||
| 10527 | else => try self.asmRegisterRegister(mir_tag, dst_alias, src_alias), | ||
| 10528 | } | ||
| 10529 | 10823 | ||
| 10530 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 10824 | const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty, mod)); |
| 10825 | const dst_mcv = MCValue{ .register = dst_reg }; | ||
| 10826 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | ||
| 10827 | defer self.register_manager.unlockReg(dst_lock); | ||
| 10828 | |||
| 10829 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(mod)) { | ||
| 10830 | .Float => switch (dst_ty.floatBits(self.target.*)) { | ||
| 10831 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 }, | ||
| 10832 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 }, | ||
| 10833 | 16, 80, 128 => null, | ||
| 10834 | else => unreachable, | ||
| 10835 | }, | ||
| 10836 | else => null, | ||
| 10837 | }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{ | ||
| 10838 | src_ty.fmt(mod), dst_ty.fmt(mod), | ||
| 10839 | }); | ||
| 10840 | const dst_alias = dst_reg.to128(); | ||
| 10841 | const src_alias = registerAlias(src_reg, src_size); | ||
| 10842 | switch (mir_tag[0]) { | ||
| 10843 | .v_ss, .v_sd => try self.asmRegisterRegisterRegister(mir_tag, dst_alias, dst_alias, src_alias), | ||
| 10844 | else => try self.asmRegisterRegister(mir_tag, dst_alias, src_alias), | ||
| 10845 | } | ||
| 10846 | |||
| 10847 | break :result dst_mcv; | ||
| 10848 | }; | ||
| 10849 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | ||
| 10531 | } | 10850 | } |
| 10532 | 10851 | ||
| 10533 | fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { | 10852 | fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 10534 | const mod = self.bin_file.options.module.?; | 10853 | const mod = self.bin_file.options.module.?; |
| 10535 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 10854 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 10536 | 10855 | ||
| 10537 | const src_ty = self.typeOf(ty_op.operand); | ||
| 10538 | const dst_ty = self.typeOfIndex(inst); | 10856 | const dst_ty = self.typeOfIndex(inst); |
| 10539 | const dst_bits: u32 = @intCast(dst_ty.bitSize(mod)); | 10857 | const dst_bits: u32 = @intCast(dst_ty.bitSize(mod)); |
| 10540 | const dst_signedness = | 10858 | const dst_signedness = |
| 10541 | if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned; | 10859 | if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned; |
| 10542 | |||
| 10543 | const dst_size = math.divCeil(u32, @max(switch (dst_signedness) { | 10860 | const dst_size = math.divCeil(u32, @max(switch (dst_signedness) { |
| 10544 | .signed => dst_bits, | 10861 | .signed => dst_bits, |
| 10545 | .unsigned => dst_bits + 1, | 10862 | .unsigned => dst_bits + 1, |
| 10546 | }, 32), 8) catch unreachable; | 10863 | }, 32), 8) catch unreachable; |
| 10547 | if (dst_size > 8) return self.fail("TODO implement airIntFromFloat from {} to {}", .{ | ||
| 10548 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | ||
| 10549 | }); | ||
| 10550 | 10864 | ||
| 10551 | const src_mcv = try self.resolveInst(ty_op.operand); | 10865 | const src_ty = self.typeOf(ty_op.operand); |
| 10552 | const src_reg = if (src_mcv.isRegister()) | 10866 | const src_bits = src_ty.floatBits(self.target.*); |
| 10553 | src_mcv.getReg().? | ||
| 10554 | else | ||
| 10555 | try self.copyToTmpRegister(src_ty, src_mcv); | ||
| 10556 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | ||
| 10557 | defer self.register_manager.unlockReg(src_lock); | ||
| 10558 | 10867 | ||
| 10559 | const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty, mod)); | 10868 | const result = result: { |
| 10560 | const dst_mcv = MCValue{ .register = dst_reg }; | 10869 | if (switch (src_bits) { |
| 10561 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 10870 | 16, 80, 128 => true, |
| 10562 | defer self.register_manager.unlockReg(dst_lock); | 10871 | 32, 64 => dst_size > 8 and dst_size < 16, |
| 10872 | else => unreachable, | ||
| 10873 | }) { | ||
| 10874 | var callee: ["__fixuns?f?i".len]u8 = undefined; | ||
| 10875 | break :result try self.genCall(.{ .lib = .{ | ||
| 10876 | .return_type = dst_ty.toIntern(), | ||
| 10877 | .param_types = &.{src_ty.toIntern()}, | ||
| 10878 | .callee = std.fmt.bufPrint(&callee, "__fix{s}{c}f{c}i", .{ | ||
| 10879 | switch (dst_signedness) { | ||
| 10880 | .signed => "", | ||
| 10881 | .unsigned => "uns", | ||
| 10882 | }, | ||
| 10883 | floatCompilerRtAbiName(src_bits), | ||
| 10884 | intCompilerRtAbiName(dst_bits), | ||
| 10885 | }) catch unreachable, | ||
| 10886 | } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}); | ||
| 10887 | } | ||
| 10563 | 10888 | ||
| 10564 | try self.asmRegisterRegister( | 10889 | if (dst_size > 8) return self.fail("TODO implement airIntFromFloat from {} to {}", .{ |
| 10565 | @as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) { | 10890 | src_ty.fmt(mod), dst_ty.fmt(mod), |
| 10566 | .Float => switch (src_ty.floatBits(self.target.*)) { | 10891 | }); |
| 10892 | |||
| 10893 | const src_mcv = try self.resolveInst(ty_op.operand); | ||
| 10894 | const src_reg = if (src_mcv.isRegister()) | ||
| 10895 | src_mcv.getReg().? | ||
| 10896 | else | ||
| 10897 | try self.copyToTmpRegister(src_ty, src_mcv); | ||
| 10898 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | ||
| 10899 | defer self.register_manager.unlockReg(src_lock); | ||
| 10900 | |||
| 10901 | const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty, mod)); | ||
| 10902 | const dst_mcv = MCValue{ .register = dst_reg }; | ||
| 10903 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | ||
| 10904 | defer self.register_manager.unlockReg(dst_lock); | ||
| 10905 | |||
| 10906 | try self.asmRegisterRegister( | ||
| 10907 | switch (src_bits) { | ||
| 10567 | 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si }, | 10908 | 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si }, |
| 10568 | 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si }, | 10909 | 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si }, |
| 10569 | 16, 80, 128 => null, | ||
| 10570 | else => unreachable, | 10910 | else => unreachable, |
| 10571 | }, | 10911 | }, |
| 10572 | else => null, | 10912 | registerAlias(dst_reg, dst_size), |
| 10573 | }) orelse return self.fail("TODO implement airIntFromFloat from {} to {}", .{ | 10913 | src_reg.to128(), |
| 10574 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 10914 | ); |
| 10575 | }), | ||
| 10576 | registerAlias(dst_reg, dst_size), | ||
| 10577 | src_reg.to128(), | ||
| 10578 | ); | ||
| 10579 | 10915 | ||
| 10580 | if (dst_bits < dst_size * 8) try self.truncateRegister(dst_ty, dst_reg); | 10916 | if (dst_bits < dst_size * 8) try self.truncateRegister(dst_ty, dst_reg); |
| 10581 | 10917 | ||
| 10582 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 10918 | break :result dst_mcv; |
| 10919 | }; | ||
| 10920 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | ||
| 10583 | } | 10921 | } |
| 10584 | 10922 | ||
| 10585 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | 10923 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -11906,7 +12244,7 @@ const CallMCValues = struct { | ... | @@ -11906,7 +12244,7 @@ const CallMCValues = struct { |
| 11906 | fn resolveCallingConventionValues( | 12244 | fn resolveCallingConventionValues( |
| 11907 | self: *Self, | 12245 | self: *Self, |
| 11908 | fn_info: InternPool.Key.FuncType, | 12246 | fn_info: InternPool.Key.FuncType, |
| 11909 | var_args: []const Air.Inst.Ref, | 12247 | var_args: []const Type, |
| 11910 | stack_frame_base: FrameIndex, | 12248 | stack_frame_base: FrameIndex, |
| 11911 | ) !CallMCValues { | 12249 | ) !CallMCValues { |
| 11912 | const mod = self.bin_file.options.module.?; | 12250 | const mod = self.bin_file.options.module.?; |
| ... | @@ -11919,9 +12257,7 @@ fn resolveCallingConventionValues( | ... | @@ -11919,9 +12257,7 @@ fn resolveCallingConventionValues( |
| 11919 | dest.* = src.toType(); | 12257 | dest.* = src.toType(); |
| 11920 | } | 12258 | } |
| 11921 | // TODO: promote var arg types | 12259 | // TODO: promote var arg types |
| 11922 | for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg| { | 12260 | for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty| param_ty.* = arg_ty; |
| 11923 | param_ty.* = self.typeOf(arg); | ||
| 11924 | } | ||
| 11925 | 12261 | ||
| 11926 | var result: CallMCValues = .{ | 12262 | var result: CallMCValues = .{ |
| 11927 | .args = try self.gpa.alloc(MCValue, param_types.len), | 12263 | .args = try self.gpa.alloc(MCValue, param_types.len), |
| ... | @@ -12230,3 +12566,52 @@ fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { | ... | @@ -12230,3 +12566,52 @@ fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 12230 | const mod = self.bin_file.options.module.?; | 12566 | const mod = self.bin_file.options.module.?; |
| 12231 | return self.air.typeOfIndex(inst, &mod.intern_pool); | 12567 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 12232 | } | 12568 | } |
| 12569 | |||
| 12570 | fn intCompilerRtAbiName(int_bits: u32) u8 { | ||
| 12571 | return switch (int_bits) { | ||
| 12572 | 1...32 => 's', | ||
| 12573 | 33...64 => 'd', | ||
| 12574 | 65...128 => 't', | ||
| 12575 | else => unreachable, | ||
| 12576 | }; | ||
| 12577 | } | ||
| 12578 | |||
| 12579 | fn floatCompilerRtAbiName(float_bits: u32) u8 { | ||
| 12580 | return switch (float_bits) { | ||
| 12581 | 16 => 'h', | ||
| 12582 | 32 => 's', | ||
| 12583 | 64 => 'd', | ||
| 12584 | 80 => 'x', | ||
| 12585 | 128 => 't', | ||
| 12586 | else => unreachable, | ||
| 12587 | }; | ||
| 12588 | } | ||
| 12589 | |||
| 12590 | fn floatCompilerRtAbiType(self: *Self, ty: Type, other_ty: Type) Type { | ||
| 12591 | if (ty.toIntern() == .f16_type and | ||
| 12592 | (other_ty.toIntern() == .f32_type or other_ty.toIntern() == .f64_type) and | ||
| 12593 | self.target.isDarwin()) return Type.u16; | ||
| 12594 | return ty; | ||
| 12595 | } | ||
| 12596 | |||
| 12597 | fn floatLibcAbiPrefix(ty: Type) []const u8 { | ||
| 12598 | return switch (ty.toIntern()) { | ||
| 12599 | .f16_type, | ||
| 12600 | .f80_type, | ||
| 12601 | => "__", | ||
| 12602 | .f32_type, .f64_type, .f128_type, .c_longdouble_type => "", | ||
| 12603 | else => unreachable, | ||
| 12604 | }; | ||
| 12605 | } | ||
| 12606 | |||
| 12607 | fn floatLibcAbiSuffix(ty: Type) []const u8 { | ||
| 12608 | return switch (ty.toIntern()) { | ||
| 12609 | .f16_type => "h", | ||
| 12610 | .f32_type => "f", | ||
| 12611 | .f64_type => "", | ||
| 12612 | .f80_type => "x", | ||
| 12613 | .f128_type => "q", | ||
| 12614 | .c_longdouble_type => "l", | ||
| 12615 | else => unreachable, | ||
| 12616 | }; | ||
| 12617 | } |
src/arch/x86_64/abi.zig+2-2| ... | @@ -444,7 +444,7 @@ pub const SysV = struct { | ... | @@ -444,7 +444,7 @@ pub const SysV = struct { |
| 444 | /// These registers need to be preserved (saved on the stack) and restored by the caller before | 444 | /// These registers need to be preserved (saved on the stack) and restored by the caller before |
| 445 | /// the caller relinquishes control to a subroutine via call instruction (or similar). | 445 | /// the caller relinquishes control to a subroutine via call instruction (or similar). |
| 446 | /// In other words, these registers are free to use by the callee. | 446 | /// In other words, these registers are free to use by the callee. |
| 447 | pub const caller_preserved_regs = [_]Register{ .rax, .rcx, .rdx, .rsi, .rdi, .r8, .r9, .r10, .r11 }; | 447 | pub const caller_preserved_regs = [_]Register{ .rax, .rcx, .rdx, .rsi, .rdi, .r8, .r9, .r10, .r11 } ++ sse_avx_regs; |
| 448 | 448 | ||
| 449 | pub const c_abi_int_param_regs = [_]Register{ .rdi, .rsi, .rdx, .rcx, .r8, .r9 }; | 449 | pub const c_abi_int_param_regs = [_]Register{ .rdi, .rsi, .rdx, .rcx, .r8, .r9 }; |
| 450 | pub const c_abi_int_return_regs = [_]Register{ .rax, .rdx }; | 450 | pub const c_abi_int_return_regs = [_]Register{ .rax, .rdx }; |
| ... | @@ -457,7 +457,7 @@ pub const Win64 = struct { | ... | @@ -457,7 +457,7 @@ pub const Win64 = struct { |
| 457 | /// These registers need to be preserved (saved on the stack) and restored by the caller before | 457 | /// These registers need to be preserved (saved on the stack) and restored by the caller before |
| 458 | /// the caller relinquishes control to a subroutine via call instruction (or similar). | 458 | /// the caller relinquishes control to a subroutine via call instruction (or similar). |
| 459 | /// In other words, these registers are free to use by the callee. | 459 | /// In other words, these registers are free to use by the callee. |
| 460 | pub const caller_preserved_regs = [_]Register{ .rax, .rcx, .rdx, .r8, .r9, .r10, .r11 }; | 460 | pub const caller_preserved_regs = [_]Register{ .rax, .rcx, .rdx, .r8, .r9, .r10, .r11 } ++ sse_avx_regs; |
| 461 | 461 | ||
| 462 | pub const c_abi_int_param_regs = [_]Register{ .rcx, .rdx, .r8, .r9 }; | 462 | pub const c_abi_int_param_regs = [_]Register{ .rcx, .rdx, .r8, .r9 }; |
| 463 | pub const c_abi_int_return_regs = [_]Register{.rax}; | 463 | pub const c_abi_int_return_regs = [_]Register{.rax}; |
src/codegen/llvm.zig-9| ... | @@ -6394,15 +6394,6 @@ pub const FuncGen = struct { | ... | @@ -6394,15 +6394,6 @@ pub const FuncGen = struct { |
| 6394 | const fn_ty = try mod.funcType(.{ | 6394 | const fn_ty = try mod.funcType(.{ |
| 6395 | .param_types = &.{}, | 6395 | .param_types = &.{}, |
| 6396 | .return_type = .void_type, | 6396 | .return_type = .void_type, |
| 6397 | .alignment = .none, | ||
| 6398 | .noalias_bits = 0, | ||
| 6399 | .comptime_bits = 0, | ||
| 6400 | .cc = .Unspecified, | ||
| 6401 | .is_var_args = false, | ||
| 6402 | .is_generic = false, | ||
| 6403 | .is_noinline = false, | ||
| 6404 | .section_is_generic = false, | ||
| 6405 | .addrspace_is_generic = false, | ||
| 6406 | }); | 6397 | }); |
| 6407 | const fn_di_ty = try o.lowerDebugType(fn_ty, .full); | 6398 | const fn_di_ty = try o.lowerDebugType(fn_ty, .full); |
| 6408 | const subprogram = dib.createFunction( | 6399 | const subprogram = dib.createFunction( |
test/behavior/abs.zig+2-1| ... | @@ -86,9 +86,10 @@ test "@abs floats" { | ... | @@ -86,9 +86,10 @@ test "@abs floats" { |
| 86 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO | 86 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO |
| 87 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 87 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 88 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 88 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 89 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 89 | 90 | ||
| 90 | try comptime testAbsFloats(f16); | 91 | try comptime testAbsFloats(f16); |
| 91 | if (builtin.zig_backend != .stage2_x86_64) try testAbsFloats(f16); | 92 | try testAbsFloats(f16); |
| 92 | try comptime testAbsFloats(f32); | 93 | try comptime testAbsFloats(f32); |
| 93 | try testAbsFloats(f32); | 94 | try testAbsFloats(f32); |
| 94 | try comptime testAbsFloats(f64); | 95 | try comptime testAbsFloats(f64); |
test/behavior/asm.zig-2| ... | @@ -85,7 +85,6 @@ test "alternative constraints" { | ... | @@ -85,7 +85,6 @@ test "alternative constraints" { |
| 85 | 85 | ||
| 86 | test "sized integer/float in asm input" { | 86 | test "sized integer/float in asm input" { |
| 87 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 87 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 88 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 89 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 88 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 90 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 89 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 91 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 90 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -137,7 +136,6 @@ test "sized integer/float in asm input" { | ... | @@ -137,7 +136,6 @@ test "sized integer/float in asm input" { |
| 137 | 136 | ||
| 138 | test "struct/array/union types as input values" { | 137 | test "struct/array/union types as input values" { |
| 139 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 138 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 140 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 141 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 139 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 142 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 140 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 143 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 141 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/bitcast.zig-2| ... | @@ -470,7 +470,6 @@ test "@bitCast of packed struct of bools all true" { | ... | @@ -470,7 +470,6 @@ test "@bitCast of packed struct of bools all true" { |
| 470 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 470 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 471 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 471 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 472 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 472 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 473 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 474 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 473 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 475 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 474 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 476 | 475 | ||
| ... | @@ -492,7 +491,6 @@ test "@bitCast of packed struct of bools all false" { | ... | @@ -492,7 +491,6 @@ test "@bitCast of packed struct of bools all false" { |
| 492 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 491 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 493 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 492 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 494 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 493 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 495 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 496 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 494 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 497 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 495 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 498 | 496 |
test/behavior/bugs/12680.zig+2-1| ... | @@ -9,9 +9,10 @@ test "export a function twice" { | ... | @@ -9,9 +9,10 @@ test "export a function twice" { |
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 11 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 11 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 13 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 12 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 14 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 13 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 14 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 15 | |||
| 15 | if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) { | 16 | if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) { |
| 16 | // TODO: test.c: error: aliases are not supported on darwin | 17 | // TODO: test.c: error: aliases are not supported on darwin |
| 17 | return error.SkipZigTest; | 18 | return error.SkipZigTest; |
test/behavior/bugs/529.zig+1-1| ... | @@ -11,11 +11,11 @@ comptime { | ... | @@ -11,11 +11,11 @@ comptime { |
| 11 | const builtin = @import("builtin"); | 11 | const builtin = @import("builtin"); |
| 12 | 12 | ||
| 13 | test "issue 529 fixed" { | 13 | test "issue 529 fixed" { |
| 14 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 18 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 17 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 18 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 19 | 19 | ||
| 20 | @import("529_other_file.zig").issue529(null); | 20 | @import("529_other_file.zig").issue529(null); |
| 21 | issue529(null); | 21 | issue529(null); |
test/behavior/cast.zig-23| ... | @@ -1611,7 +1611,6 @@ test "coercion from single-item pointer to @as to slice" { | ... | @@ -1611,7 +1611,6 @@ test "coercion from single-item pointer to @as to slice" { |
| 1611 | test "peer type resolution: const sentinel slice and mutable non-sentinel slice" { | 1611 | test "peer type resolution: const sentinel slice and mutable non-sentinel slice" { |
| 1612 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1612 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1614 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1615 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1614 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1616 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1615 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1617 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1616 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1664,7 +1663,6 @@ test "peer type resolution: float and comptime-known fixed-width integer" { | ... | @@ -1664,7 +1663,6 @@ test "peer type resolution: float and comptime-known fixed-width integer" { |
| 1664 | test "peer type resolution: same array type with sentinel" { | 1663 | test "peer type resolution: same array type with sentinel" { |
| 1665 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1664 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1666 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1665 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1667 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1668 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1666 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1669 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1667 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1670 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1668 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1687,7 +1685,6 @@ test "peer type resolution: same array type with sentinel" { | ... | @@ -1687,7 +1685,6 @@ test "peer type resolution: same array type with sentinel" { |
| 1687 | test "peer type resolution: array with sentinel and array without sentinel" { | 1685 | test "peer type resolution: array with sentinel and array without sentinel" { |
| 1688 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1686 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1689 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1687 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1690 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1691 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1688 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1692 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1689 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1693 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1690 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1710,7 +1707,6 @@ test "peer type resolution: array with sentinel and array without sentinel" { | ... | @@ -1710,7 +1707,6 @@ test "peer type resolution: array with sentinel and array without sentinel" { |
| 1710 | test "peer type resolution: array and vector with same child type" { | 1707 | test "peer type resolution: array and vector with same child type" { |
| 1711 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1708 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1712 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1709 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1713 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1714 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1710 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1715 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1711 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1716 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1712 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1756,7 +1752,6 @@ test "peer type resolution: array with smaller child type and vector with larger | ... | @@ -1756,7 +1752,6 @@ test "peer type resolution: array with smaller child type and vector with larger |
| 1756 | test "peer type resolution: error union and optional of same type" { | 1752 | test "peer type resolution: error union and optional of same type" { |
| 1757 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1753 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1758 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1754 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1759 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1760 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1755 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1761 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1756 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1762 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1757 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1780,7 +1775,6 @@ test "peer type resolution: error union and optional of same type" { | ... | @@ -1780,7 +1775,6 @@ test "peer type resolution: error union and optional of same type" { |
| 1780 | test "peer type resolution: C pointer and @TypeOf(null)" { | 1775 | test "peer type resolution: C pointer and @TypeOf(null)" { |
| 1781 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1776 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1782 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1777 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1783 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1784 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1778 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1785 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1779 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1786 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1780 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1803,7 +1797,6 @@ test "peer type resolution: C pointer and @TypeOf(null)" { | ... | @@ -1803,7 +1797,6 @@ test "peer type resolution: C pointer and @TypeOf(null)" { |
| 1803 | test "peer type resolution: three-way resolution combines error set and optional" { | 1797 | test "peer type resolution: three-way resolution combines error set and optional" { |
| 1804 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1798 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1805 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1799 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1806 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1807 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1800 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1808 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1801 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1809 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1802 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1846,7 +1839,6 @@ test "peer type resolution: three-way resolution combines error set and optional | ... | @@ -1846,7 +1839,6 @@ test "peer type resolution: three-way resolution combines error set and optional |
| 1846 | test "peer type resolution: vector and optional vector" { | 1839 | test "peer type resolution: vector and optional vector" { |
| 1847 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1840 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1848 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1841 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1849 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1850 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1842 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1851 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1843 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1852 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1844 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1869,7 +1861,6 @@ test "peer type resolution: vector and optional vector" { | ... | @@ -1869,7 +1861,6 @@ test "peer type resolution: vector and optional vector" { |
| 1869 | test "peer type resolution: optional fixed-width int and comptime_int" { | 1861 | test "peer type resolution: optional fixed-width int and comptime_int" { |
| 1870 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1862 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1871 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1863 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1872 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1873 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1864 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1874 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1865 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1875 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1866 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1892,7 +1883,6 @@ test "peer type resolution: optional fixed-width int and comptime_int" { | ... | @@ -1892,7 +1883,6 @@ test "peer type resolution: optional fixed-width int and comptime_int" { |
| 1892 | test "peer type resolution: array and tuple" { | 1883 | test "peer type resolution: array and tuple" { |
| 1893 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1884 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1894 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1885 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1895 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1896 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1886 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1897 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1887 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1898 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1888 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1916,7 +1906,6 @@ test "peer type resolution: array and tuple" { | ... | @@ -1916,7 +1906,6 @@ test "peer type resolution: array and tuple" { |
| 1916 | test "peer type resolution: vector and tuple" { | 1906 | test "peer type resolution: vector and tuple" { |
| 1917 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1907 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1918 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1908 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1919 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1920 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1909 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1921 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1910 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1922 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1911 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1940,7 +1929,6 @@ test "peer type resolution: vector and tuple" { | ... | @@ -1940,7 +1929,6 @@ test "peer type resolution: vector and tuple" { |
| 1940 | test "peer type resolution: vector and array and tuple" { | 1929 | test "peer type resolution: vector and array and tuple" { |
| 1941 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1930 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1942 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1931 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1943 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1944 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1932 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1945 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1933 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1946 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1934 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -1983,7 +1971,6 @@ test "peer type resolution: vector and array and tuple" { | ... | @@ -1983,7 +1971,6 @@ test "peer type resolution: vector and array and tuple" { |
| 1983 | test "peer type resolution: empty tuple pointer and slice" { | 1971 | test "peer type resolution: empty tuple pointer and slice" { |
| 1984 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1972 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1985 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1973 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1986 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1987 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1974 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1988 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1975 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1989 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1976 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2005,7 +1992,6 @@ test "peer type resolution: empty tuple pointer and slice" { | ... | @@ -2005,7 +1992,6 @@ test "peer type resolution: empty tuple pointer and slice" { |
| 2005 | test "peer type resolution: tuple pointer and slice" { | 1992 | test "peer type resolution: tuple pointer and slice" { |
| 2006 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1993 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2007 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1994 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2008 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2009 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1995 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2010 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1996 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2011 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1997 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2027,7 +2013,6 @@ test "peer type resolution: tuple pointer and slice" { | ... | @@ -2027,7 +2013,6 @@ test "peer type resolution: tuple pointer and slice" { |
| 2027 | test "peer type resolution: tuple pointer and optional slice" { | 2013 | test "peer type resolution: tuple pointer and optional slice" { |
| 2028 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2014 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2029 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2015 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2030 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2031 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2016 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2032 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2017 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2033 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2018 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2049,7 +2034,6 @@ test "peer type resolution: tuple pointer and optional slice" { | ... | @@ -2049,7 +2034,6 @@ test "peer type resolution: tuple pointer and optional slice" { |
| 2049 | test "peer type resolution: many compatible pointers" { | 2034 | test "peer type resolution: many compatible pointers" { |
| 2050 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2035 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2051 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2036 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2052 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2053 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2037 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2054 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2038 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2055 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2039 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2116,7 +2100,6 @@ test "peer type resolution: many compatible pointers" { | ... | @@ -2116,7 +2100,6 @@ test "peer type resolution: many compatible pointers" { |
| 2116 | test "peer type resolution: tuples with comptime fields" { | 2100 | test "peer type resolution: tuples with comptime fields" { |
| 2117 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2101 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2118 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2119 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2120 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2103 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2121 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2104 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2122 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2105 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2149,7 +2132,6 @@ test "peer type resolution: tuples with comptime fields" { | ... | @@ -2149,7 +2132,6 @@ test "peer type resolution: tuples with comptime fields" { |
| 2149 | test "peer type resolution: C pointer and many pointer" { | 2132 | test "peer type resolution: C pointer and many pointer" { |
| 2150 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2133 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2151 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2134 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2152 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2153 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2135 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2154 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2136 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2155 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2137 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2173,7 +2155,6 @@ test "peer type resolution: C pointer and many pointer" { | ... | @@ -2173,7 +2155,6 @@ test "peer type resolution: C pointer and many pointer" { |
| 2173 | test "peer type resolution: pointer attributes are combined correctly" { | 2155 | test "peer type resolution: pointer attributes are combined correctly" { |
| 2174 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2156 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2175 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2157 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2176 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2177 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2158 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2178 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2159 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2179 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2160 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2218,7 +2199,6 @@ test "peer type resolution: pointer attributes are combined correctly" { | ... | @@ -2218,7 +2199,6 @@ test "peer type resolution: pointer attributes are combined correctly" { |
| 2218 | test "cast builtins can wrap result in optional" { | 2199 | test "cast builtins can wrap result in optional" { |
| 2219 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2200 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2220 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2221 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2222 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2202 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2223 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2203 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2224 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2204 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2258,7 +2238,6 @@ test "cast builtins can wrap result in optional" { | ... | @@ -2258,7 +2238,6 @@ test "cast builtins can wrap result in optional" { |
| 2258 | test "cast builtins can wrap result in error union" { | 2238 | test "cast builtins can wrap result in error union" { |
| 2259 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2239 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2260 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2240 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2261 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2262 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2241 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2263 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2242 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2264 | 2243 | ||
| ... | @@ -2298,7 +2277,6 @@ test "cast builtins can wrap result in error union" { | ... | @@ -2298,7 +2277,6 @@ test "cast builtins can wrap result in error union" { |
| 2298 | test "cast builtins can wrap result in error union and optional" { | 2277 | test "cast builtins can wrap result in error union and optional" { |
| 2299 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2278 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2300 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2279 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2301 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2302 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2280 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2303 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2281 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 2304 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 2282 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| ... | @@ -2496,7 +2474,6 @@ test "@as does not corrupt values with incompatible representations" { | ... | @@ -2496,7 +2474,6 @@ test "@as does not corrupt values with incompatible representations" { |
| 2496 | 2474 | ||
| 2497 | test "result information is preserved through many nested structures" { | 2475 | test "result information is preserved through many nested structures" { |
| 2498 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 2476 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 2499 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 2500 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 2477 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 2501 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 2478 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 2502 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 2479 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/defer.zig-1| ... | @@ -133,7 +133,6 @@ test "errdefer with payload" { | ... | @@ -133,7 +133,6 @@ test "errdefer with payload" { |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | test "reference to errdefer payload" { | 135 | test "reference to errdefer payload" { |
| 136 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 137 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 136 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 138 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 137 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 139 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 138 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
test/behavior/floatop.zig+907-703| ... | @@ -2,16 +2,8 @@ const std = @import("std"); | ... | @@ -2,16 +2,8 @@ const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | const math = std.math; | 4 | const math = std.math; |
| 5 | const pi = std.math.pi; | 5 | |
| 6 | const e = std.math.e; | 6 | const epsilon_16 = 0.002; |
| 7 | const has_f80_rt = switch (builtin.cpu.arch) { | ||
| 8 | .x86_64, .x86 => true, | ||
| 9 | else => false, | ||
| 10 | }; | ||
| 11 | const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and | ||
| 12 | !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c); | ||
| 13 | |||
| 14 | const epsilon_16 = 0.001; | ||
| 15 | const epsilon = 0.000001; | 7 | const epsilon = 0.000001; |
| 16 | 8 | ||
| 17 | fn epsForType(comptime T: type) T { | 9 | fn epsForType(comptime T: type) T { |
| ... | @@ -21,44 +13,195 @@ fn epsForType(comptime T: type) T { | ... | @@ -21,44 +13,195 @@ fn epsForType(comptime T: type) T { |
| 21 | }; | 13 | }; |
| 22 | } | 14 | } |
| 23 | 15 | ||
| 24 | test "floating point comparisons" { | 16 | test "add f16" { |
| 17 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 18 | |||
| 19 | try testAdd(f16); | ||
| 20 | try comptime testAdd(f16); | ||
| 21 | } | ||
| 22 | |||
| 23 | test "add f32/f64" { | ||
| 24 | try testAdd(f32); | ||
| 25 | try comptime testAdd(f32); | ||
| 26 | try testAdd(f64); | ||
| 27 | try comptime testAdd(f64); | ||
| 28 | } | ||
| 29 | |||
| 30 | test "add f80/f128/c_longdouble" { | ||
| 31 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 32 | |||
| 33 | try testAdd(f80); | ||
| 34 | try comptime testAdd(f80); | ||
| 35 | try testAdd(f128); | ||
| 36 | try comptime testAdd(f128); | ||
| 37 | try testAdd(c_longdouble); | ||
| 38 | try comptime testAdd(c_longdouble); | ||
| 39 | } | ||
| 40 | |||
| 41 | fn testAdd(comptime T: type) !void { | ||
| 42 | var one_point_two_five: T = 1.25; | ||
| 43 | var two_point_seven_five: T = 2.75; | ||
| 44 | try expect(one_point_two_five + two_point_seven_five == 4); | ||
| 45 | } | ||
| 46 | |||
| 47 | test "sub f16" { | ||
| 48 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 49 | |||
| 50 | try testSub(f16); | ||
| 51 | try comptime testSub(f16); | ||
| 52 | } | ||
| 53 | |||
| 54 | test "sub f32/f64" { | ||
| 55 | try testSub(f32); | ||
| 56 | try comptime testSub(f32); | ||
| 57 | try testSub(f64); | ||
| 58 | try comptime testSub(f64); | ||
| 59 | } | ||
| 60 | |||
| 61 | test "sub f80/f128/c_longdouble" { | ||
| 62 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 63 | |||
| 64 | try testSub(f80); | ||
| 65 | try comptime testSub(f80); | ||
| 66 | try testSub(f128); | ||
| 67 | try comptime testSub(f128); | ||
| 68 | try testSub(c_longdouble); | ||
| 69 | try comptime testSub(c_longdouble); | ||
| 70 | } | ||
| 71 | |||
| 72 | fn testSub(comptime T: type) !void { | ||
| 73 | var one_point_two_five: T = 1.25; | ||
| 74 | var two_point_seven_five: T = 2.75; | ||
| 75 | try expect(one_point_two_five - two_point_seven_five == -1.5); | ||
| 76 | } | ||
| 77 | |||
| 78 | test "mul f16" { | ||
| 79 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 80 | |||
| 81 | try testMul(f16); | ||
| 82 | try comptime testMul(f16); | ||
| 83 | } | ||
| 84 | |||
| 85 | test "mul f32/f64" { | ||
| 86 | try testMul(f32); | ||
| 87 | try comptime testMul(f32); | ||
| 88 | try testMul(f64); | ||
| 89 | try comptime testMul(f64); | ||
| 90 | } | ||
| 91 | |||
| 92 | test "mul f80/f128/c_longdouble" { | ||
| 93 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 94 | |||
| 95 | try testMul(f80); | ||
| 96 | try comptime testMul(f80); | ||
| 97 | try testMul(f128); | ||
| 98 | try comptime testMul(f128); | ||
| 99 | try testMul(c_longdouble); | ||
| 100 | try comptime testMul(c_longdouble); | ||
| 101 | } | ||
| 102 | |||
| 103 | fn testMul(comptime T: type) !void { | ||
| 104 | var one_point_two_five: T = 1.25; | ||
| 105 | var two_point_seven_five: T = 2.75; | ||
| 106 | try expect(one_point_two_five * two_point_seven_five == 3.4375); | ||
| 107 | } | ||
| 108 | |||
| 109 | test "cmp f16" { | ||
| 110 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 111 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 112 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 113 | |||
| 114 | try testCmp(f16); | ||
| 115 | try comptime testCmp(f16); | ||
| 116 | } | ||
| 117 | |||
| 118 | test "cmp f32/f64" { | ||
| 25 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 119 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 120 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 26 | 121 | ||
| 27 | try testFloatComparisons(); | 122 | try testCmp(f32); |
| 28 | try comptime testFloatComparisons(); | 123 | try comptime testCmp(f32); |
| 124 | try testCmp(f64); | ||
| 125 | try comptime testCmp(f64); | ||
| 29 | } | 126 | } |
| 30 | 127 | ||
| 31 | fn testFloatComparisons() !void { | 128 | test "cmp f128" { |
| 32 | inline for ([_]type{ f16, f32, f64, f128 }) |ty| { | 129 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 130 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 131 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 132 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 133 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 134 | |||
| 135 | try testCmp(f128); | ||
| 136 | try comptime testCmp(f128); | ||
| 137 | } | ||
| 138 | |||
| 139 | test "cmp f80/c_longdouble" { | ||
| 140 | if (true) return error.SkipZigTest; | ||
| 141 | |||
| 142 | try testCmp(f80); | ||
| 143 | try comptime testCmp(f80); | ||
| 144 | try testCmp(c_longdouble); | ||
| 145 | try comptime testCmp(c_longdouble); | ||
| 146 | } | ||
| 147 | |||
| 148 | fn testCmp(comptime T: type) !void { | ||
| 149 | { | ||
| 33 | // No decimal part | 150 | // No decimal part |
| 34 | { | 151 | var x: T = 1.0; |
| 35 | const x: ty = 1.0; | 152 | try expect(x == 1.0); |
| 36 | try expect(x == 1); | 153 | try expect(x != 0.0); |
| 37 | try expect(x != 0); | 154 | try expect(x > 0.0); |
| 38 | try expect(x > 0); | 155 | try expect(x < 2.0); |
| 39 | try expect(x < 2); | 156 | try expect(x >= 1.0); |
| 40 | try expect(x >= 1); | 157 | try expect(x <= 1.0); |
| 41 | try expect(x <= 1); | 158 | } |
| 42 | } | 159 | { |
| 43 | // Non-zero decimal part | 160 | // Non-zero decimal part |
| 44 | { | 161 | var x: T = 1.5; |
| 45 | const x: ty = 1.5; | 162 | try expect(x != 1.0); |
| 46 | try expect(x != 1); | 163 | try expect(x != 2.0); |
| 47 | try expect(x != 2); | 164 | try expect(x > 1.0); |
| 48 | try expect(x > 1); | 165 | try expect(x < 2.0); |
| 49 | try expect(x < 2); | 166 | try expect(x >= 1.0); |
| 50 | try expect(x >= 1); | 167 | try expect(x <= 2.0); |
| 51 | try expect(x <= 2); | 168 | } |
| 169 | |||
| 170 | @setEvalBranchQuota(2_000); | ||
| 171 | var edges = [_]T{ | ||
| 172 | -math.inf(T), | ||
| 173 | -math.floatMax(T), | ||
| 174 | -math.floatMin(T), | ||
| 175 | -math.floatTrueMin(T), | ||
| 176 | -0.0, | ||
| 177 | math.nan(T), | ||
| 178 | 0.0, | ||
| 179 | math.floatTrueMin(T), | ||
| 180 | math.floatMin(T), | ||
| 181 | math.floatMax(T), | ||
| 182 | math.inf(T), | ||
| 183 | }; | ||
| 184 | for (edges, 0..) |rhs, rhs_i| { | ||
| 185 | for (edges, 0..) |lhs, lhs_i| { | ||
| 186 | const no_nan = lhs_i != 5 and rhs_i != 5; | ||
| 187 | const lhs_order = if (lhs_i < 5) lhs_i else lhs_i - 2; | ||
| 188 | const rhs_order = if (rhs_i < 5) rhs_i else rhs_i - 2; | ||
| 189 | try expect((lhs == rhs) == (no_nan and lhs_order == rhs_order)); | ||
| 190 | try expect((lhs != rhs) == !(no_nan and lhs_order == rhs_order)); | ||
| 191 | try expect((lhs < rhs) == (no_nan and lhs_order < rhs_order)); | ||
| 192 | try expect((lhs > rhs) == (no_nan and lhs_order > rhs_order)); | ||
| 193 | try expect((lhs <= rhs) == (no_nan and lhs_order <= rhs_order)); | ||
| 194 | try expect((lhs >= rhs) == (no_nan and lhs_order >= rhs_order)); | ||
| 52 | } | 195 | } |
| 53 | } | 196 | } |
| 54 | } | 197 | } |
| 55 | 198 | ||
| 56 | test "different sized float comparisons" { | 199 | test "different sized float comparisons" { |
| 57 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 58 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 200 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 201 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 60 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 61 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 203 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 204 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 62 | 205 | ||
| 63 | try testDifferentSizedFloatComparisons(); | 206 | try testDifferentSizedFloatComparisons(); |
| 64 | try comptime testDifferentSizedFloatComparisons(); | 207 | try comptime testDifferentSizedFloatComparisons(); |
| ... | @@ -70,27 +213,6 @@ fn testDifferentSizedFloatComparisons() !void { | ... | @@ -70,27 +213,6 @@ fn testDifferentSizedFloatComparisons() !void { |
| 70 | try expect(a < b); | 213 | try expect(a < b); |
| 71 | } | 214 | } |
| 72 | 215 | ||
| 73 | test "f80 comparisons" { | ||
| 74 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 75 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 76 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 77 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 78 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 79 | |||
| 80 | try expect(compareF80(0.0, .eq, -0.0)); | ||
| 81 | try expect(compareF80(0.0, .lte, -0.0)); | ||
| 82 | try expect(compareF80(0.0, .gte, -0.0)); | ||
| 83 | try expect(compareF80(1.0, .neq, -1.0)); | ||
| 84 | try expect(compareF80(2.0, .lt, 4.0)); | ||
| 85 | try expect(compareF80(2.0, .lte, 4.0)); | ||
| 86 | try expect(compareF80(-2.0, .gt, -4.0)); | ||
| 87 | try expect(compareF80(-2.0, .gte, -4.0)); | ||
| 88 | } | ||
| 89 | |||
| 90 | fn compareF80(x: f80, op: math.CompareOperator, y: f80) bool { | ||
| 91 | return math.compare(x, op, y); | ||
| 92 | } | ||
| 93 | |||
| 94 | // TODO This is waiting on library support for the Windows build (not sure why the other's don't need it) | 216 | // TODO This is waiting on library support for the Windows build (not sure why the other's don't need it) |
| 95 | //test "@nearbyint" { | 217 | //test "@nearbyint" { |
| 96 | // comptime testNearbyInt(); | 218 | // comptime testNearbyInt(); |
| ... | @@ -119,42 +241,93 @@ test "negative f128 intFromFloat at compile-time" { | ... | @@ -119,42 +241,93 @@ test "negative f128 intFromFloat at compile-time" { |
| 119 | try expect(@as(i64, -2) == b); | 241 | try expect(@as(i64, -2) == b); |
| 120 | } | 242 | } |
| 121 | 243 | ||
| 122 | test "@sqrt" { | 244 | test "@sqrt f16" { |
| 123 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 245 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 124 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 246 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 125 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 247 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 126 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 248 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 249 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 127 | 250 | ||
| 128 | try comptime testSqrt(); | 251 | try testSqrt(f16); |
| 129 | try testSqrt(); | 252 | try comptime testSqrt(f16); |
| 130 | } | 253 | } |
| 131 | 254 | ||
| 132 | fn testSqrt() !void { | 255 | test "@sqrt f32/f64" { |
| 133 | try expect(@sqrt(@as(f16, 4)) == 2); | 256 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 134 | try expect(@sqrt(@as(f32, 9)) == 3); | 257 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 135 | try expect(@sqrt(@as(f64, 25)) == 5); | 258 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 136 | try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 1.1)), 1.0488088481701516, epsilon)); | 259 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 137 | try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 2.0)), 1.4142135623730950, epsilon)); | 260 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 138 | 261 | ||
| 139 | if (false) { | 262 | try testSqrt(f32); |
| 140 | if (has_f80_rt) { | 263 | try comptime testSqrt(f32); |
| 141 | // TODO https://github.com/ziglang/zig/issues/10875 | 264 | try testSqrt(f64); |
| 142 | if (builtin.os.tag != .freebsd) { | 265 | try comptime testSqrt(f64); |
| 143 | var a: f80 = 25; | 266 | } |
| 144 | try expect(@sqrt(a) == 5); | 267 | |
| 145 | } | 268 | test "@sqrt f80/f128/c_longdouble" { |
| 146 | } | 269 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 147 | { | 270 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 148 | const a: comptime_float = 25.0; | 271 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 149 | try expect(@sqrt(a) == 5.0); | 272 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 150 | } | 273 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 151 | // TODO test f128, and c_longdouble | 274 | |
| 152 | // https://github.com/ziglang/zig/issues/4026 | 275 | if (builtin.os.tag == .freebsd) { |
| 153 | //{ | 276 | // TODO https://github.com/ziglang/zig/issues/10875 |
| 154 | // var a: f128 = 49; | 277 | return error.SkipZigTest; |
| 155 | //try expect(@sqrt(a) == 7); | ||
| 156 | //} | ||
| 157 | } | 278 | } |
| 279 | |||
| 280 | try testSqrt(f80); | ||
| 281 | try comptime testSqrt(f80); | ||
| 282 | try testSqrt(f128); | ||
| 283 | try comptime testSqrt(f128); | ||
| 284 | try testSqrt(c_longdouble); | ||
| 285 | try comptime testSqrt(c_longdouble); | ||
| 286 | } | ||
| 287 | |||
| 288 | fn testSqrt(comptime T: type) !void { | ||
| 289 | const eps = epsForType(T); | ||
| 290 | var four: T = 4.0; | ||
| 291 | try expect(@sqrt(four) == 2.0); | ||
| 292 | var nine: T = 9.0; | ||
| 293 | try expect(@sqrt(nine) == 3.0); | ||
| 294 | var twenty_five: T = 25.0; | ||
| 295 | try expect(@sqrt(twenty_five) == 5.0); | ||
| 296 | var sixty_four: T = 64.0; | ||
| 297 | try expect(@sqrt(sixty_four) == 8.0); | ||
| 298 | var one_point_one: T = 1.1; | ||
| 299 | |||
| 300 | try expect(math.approxEqAbs(T, @sqrt(one_point_one), 1.0488088481701516, eps)); | ||
| 301 | var two: T = 2.0; | ||
| 302 | try expect(math.approxEqAbs(T, @sqrt(two), 1.4142135623730950, eps)); | ||
| 303 | var three_point_six: T = 3.6; | ||
| 304 | try expect(math.approxEqAbs(T, @sqrt(three_point_six), 1.8973665961010276, eps)); | ||
| 305 | var sixty_four_point_one: T = 64.1; | ||
| 306 | try expect(math.approxEqAbs(T, @sqrt(sixty_four_point_one), 8.00624756049923802, eps)); | ||
| 307 | var twelve: T = 12.0; | ||
| 308 | try expect(math.approxEqAbs(T, @sqrt(twelve), 3.46410161513775459, eps)); | ||
| 309 | var thirteen: T = 13.0; | ||
| 310 | try expect(math.approxEqAbs(T, @sqrt(thirteen), 3.60555127546398929, eps)); | ||
| 311 | var fourteen: T = 14.0; | ||
| 312 | try expect(math.approxEqAbs(T, @sqrt(fourteen), 3.74165738677394139, eps)); | ||
| 313 | var a: T = 7.539840; | ||
| 314 | try expect(math.approxEqAbs(T, @sqrt(a), 2.74587690911300684, eps)); | ||
| 315 | var b: T = 19.230934; | ||
| 316 | try expect(math.approxEqAbs(T, @sqrt(b), 4.38530888307767894, eps)); | ||
| 317 | var c: T = 8942.230469; | ||
| 318 | try expect(math.approxEqAbs(T, @sqrt(c), 94.5633674791671111, eps)); | ||
| 319 | |||
| 320 | // special cases | ||
| 321 | var inf: T = math.inf(T); | ||
| 322 | try expect(math.isPositiveInf(@sqrt(inf))); | ||
| 323 | var zero: T = 0.0; | ||
| 324 | try expect(@sqrt(zero) == 0.0); | ||
| 325 | var neg_zero: T = -0.0; | ||
| 326 | try expect(@sqrt(neg_zero) == 0.0); | ||
| 327 | var neg_one: T = -1.0; | ||
| 328 | try expect(math.isNan(@sqrt(neg_one))); | ||
| 329 | var nan: T = math.nan(T); | ||
| 330 | try expect(math.isNan(@sqrt(nan))); | ||
| 158 | } | 331 | } |
| 159 | 332 | ||
| 160 | test "@sqrt with vectors" { | 333 | test "@sqrt with vectors" { |
| ... | @@ -163,8 +336,8 @@ test "@sqrt with vectors" { | ... | @@ -163,8 +336,8 @@ test "@sqrt with vectors" { |
| 163 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 336 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 164 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 337 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 165 | 338 | ||
| 166 | try comptime testSqrtWithVectors(); | ||
| 167 | try testSqrtWithVectors(); | 339 | try testSqrtWithVectors(); |
| 340 | try comptime testSqrtWithVectors(); | ||
| 168 | } | 341 | } |
| 169 | 342 | ||
| 170 | fn testSqrtWithVectors() !void { | 343 | fn testSqrtWithVectors() !void { |
| ... | @@ -176,88 +349,64 @@ fn testSqrtWithVectors() !void { | ... | @@ -176,88 +349,64 @@ fn testSqrtWithVectors() !void { |
| 176 | try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon)); | 349 | try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon)); |
| 177 | } | 350 | } |
| 178 | 351 | ||
| 179 | test "more @sqrt f16 tests" { | 352 | test "@sin f16" { |
| 180 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 181 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 353 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 182 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 354 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 183 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 355 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 184 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 356 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 357 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 185 | 358 | ||
| 186 | // TODO these are not all passing at comptime | 359 | try testSin(f16); |
| 187 | try expect(@sqrt(@as(f16, 0.0)) == 0.0); | 360 | try comptime testSin(f16); |
| 188 | try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon)); | ||
| 189 | try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon)); | ||
| 190 | try expect(@sqrt(@as(f16, 4.0)) == 2.0); | ||
| 191 | try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 7.539840)), 2.745877, epsilon)); | ||
| 192 | try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 19.230934)), 4.385309, epsilon)); | ||
| 193 | try expect(@sqrt(@as(f16, 64.0)) == 8.0); | ||
| 194 | try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 64.1)), 8.006248, epsilon)); | ||
| 195 | try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 8942.230469)), 94.563370, epsilon)); | ||
| 196 | |||
| 197 | // special cases | ||
| 198 | try expect(math.isPositiveInf(@sqrt(@as(f16, math.inf(f16))))); | ||
| 199 | try expect(@sqrt(@as(f16, 0.0)) == 0.0); | ||
| 200 | try expect(@sqrt(@as(f16, -0.0)) == -0.0); | ||
| 201 | try expect(math.isNan(@sqrt(@as(f16, -1.0)))); | ||
| 202 | try expect(math.isNan(@sqrt(@as(f16, math.nan(f16))))); | ||
| 203 | } | 361 | } |
| 204 | 362 | ||
| 205 | test "another, possibly redundant @sqrt test" { | 363 | test "@sin f32/f64" { |
| 206 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 364 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 207 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 365 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 208 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | 366 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 209 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 367 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 368 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 210 | 369 | ||
| 211 | try testSqrtLegacy(f64, 12.0); | 370 | try testSin(f32); |
| 212 | try comptime testSqrtLegacy(f64, 12.0); | 371 | comptime try testSin(f32); |
| 213 | try testSqrtLegacy(f32, 13.0); | 372 | try testSin(f64); |
| 214 | try comptime testSqrtLegacy(f32, 13.0); | 373 | comptime try testSin(f64); |
| 215 | try testSqrtLegacy(f16, 13.0); | ||
| 216 | try comptime testSqrtLegacy(f16, 13.0); | ||
| 217 | |||
| 218 | // TODO: make this pass | ||
| 219 | if (false) { | ||
| 220 | const x = 14.0; | ||
| 221 | const y = x * x; | ||
| 222 | const z = @sqrt(y); | ||
| 223 | try comptime expect(z == x); | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | fn testSqrtLegacy(comptime T: type, x: T) !void { | ||
| 228 | try expect(@sqrt(x * x) == x); | ||
| 229 | } | 374 | } |
| 230 | 375 | ||
| 231 | test "@sin" { | 376 | test "@sin f80/f128/c_longdouble" { |
| 232 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 233 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 377 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 234 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 378 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 235 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 379 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 236 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 380 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 381 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 237 | 382 | ||
| 238 | try comptime testSin(); | 383 | try testSin(f80); |
| 239 | try testSin(); | 384 | comptime try testSin(f80); |
| 385 | try testSin(f128); | ||
| 386 | comptime try testSin(f128); | ||
| 387 | try testSin(c_longdouble); | ||
| 388 | comptime try testSin(c_longdouble); | ||
| 240 | } | 389 | } |
| 241 | 390 | ||
| 242 | fn testSin() !void { | 391 | fn testSin(comptime T: type) !void { |
| 243 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 392 | const eps = epsForType(T); |
| 244 | const eps = epsForType(ty); | 393 | var zero: T = 0; |
| 245 | try expect(@sin(@as(ty, 0)) == 0); | 394 | try expect(@sin(zero) == 0); |
| 246 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi)), 0, eps)); | 395 | var pi: T = math.pi; |
| 247 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 2.0)), 1, eps)); | 396 | try expect(math.approxEqAbs(T, @sin(pi), 0, eps)); |
| 248 | try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps)); | 397 | try expect(math.approxEqAbs(T, @sin(pi / 2.0), 1, eps)); |
| 249 | } | 398 | try expect(math.approxEqAbs(T, @sin(pi / 4.0), 0.7071067811865475, eps)); |
| 250 | } | 399 | } |
| 251 | 400 | ||
| 252 | test "@sin with vectors" { | 401 | test "@sin with vectors" { |
| 253 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 402 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 254 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 255 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 403 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 256 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 404 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 257 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 405 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 406 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 258 | 407 | ||
| 259 | try comptime testSinWithVectors(); | ||
| 260 | try testSinWithVectors(); | 408 | try testSinWithVectors(); |
| 409 | try comptime testSinWithVectors(); | ||
| 261 | } | 410 | } |
| 262 | 411 | ||
| 263 | fn testSinWithVectors() !void { | 412 | fn testSinWithVectors() !void { |
| ... | @@ -269,36 +418,64 @@ fn testSinWithVectors() !void { | ... | @@ -269,36 +418,64 @@ fn testSinWithVectors() !void { |
| 269 | try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon)); | 418 | try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon)); |
| 270 | } | 419 | } |
| 271 | 420 | ||
| 272 | test "@cos" { | 421 | test "@cos f16" { |
| 273 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 274 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 422 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 275 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 423 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 276 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 424 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 277 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 425 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 426 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 278 | 427 | ||
| 279 | try comptime testCos(); | 428 | try testCos(f16); |
| 280 | try testCos(); | 429 | try comptime testCos(f16); |
| 281 | } | 430 | } |
| 282 | 431 | ||
| 283 | fn testCos() !void { | 432 | test "@cos f32/f64" { |
| 284 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 433 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 285 | const eps = epsForType(ty); | 434 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 286 | try expect(@cos(@as(ty, 0)) == 1); | 435 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 287 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi)), -1, eps)); | 436 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 288 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 2.0)), 0, eps)); | 437 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 289 | try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps)); | 438 | |
| 290 | } | 439 | try testCos(f32); |
| 440 | try comptime testCos(f32); | ||
| 441 | try testCos(f64); | ||
| 442 | try comptime testCos(f64); | ||
| 443 | } | ||
| 444 | |||
| 445 | test "@cos f80/f128/c_longdouble" { | ||
| 446 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 447 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 448 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 449 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 450 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 451 | |||
| 452 | try testCos(f80); | ||
| 453 | try comptime testCos(f80); | ||
| 454 | try testCos(f128); | ||
| 455 | try comptime testCos(f128); | ||
| 456 | try testCos(c_longdouble); | ||
| 457 | try comptime testCos(c_longdouble); | ||
| 458 | } | ||
| 459 | |||
| 460 | fn testCos(comptime T: type) !void { | ||
| 461 | const eps = epsForType(T); | ||
| 462 | var zero: T = 0; | ||
| 463 | try expect(@cos(zero) == 1); | ||
| 464 | var pi: T = math.pi; | ||
| 465 | try expect(math.approxEqAbs(T, @cos(pi), -1, eps)); | ||
| 466 | try expect(math.approxEqAbs(T, @cos(pi / 2.0), 0, eps)); | ||
| 467 | try expect(math.approxEqAbs(T, @cos(pi / 4.0), 0.7071067811865475, eps)); | ||
| 291 | } | 468 | } |
| 292 | 469 | ||
| 293 | test "@cos with vectors" { | 470 | test "@cos with vectors" { |
| 294 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 471 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 295 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 296 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 472 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 297 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 473 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 298 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 474 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 475 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 299 | 476 | ||
| 300 | try comptime testCosWithVectors(); | ||
| 301 | try testCosWithVectors(); | 477 | try testCosWithVectors(); |
| 478 | try comptime testCosWithVectors(); | ||
| 302 | } | 479 | } |
| 303 | 480 | ||
| 304 | fn testCosWithVectors() !void { | 481 | fn testCosWithVectors() !void { |
| ... | @@ -310,35 +487,133 @@ fn testCosWithVectors() !void { | ... | @@ -310,35 +487,133 @@ fn testCosWithVectors() !void { |
| 310 | try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon)); | 487 | try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon)); |
| 311 | } | 488 | } |
| 312 | 489 | ||
| 313 | test "@exp" { | 490 | test "@tan f16" { |
| 314 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 315 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 491 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 316 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 492 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 317 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 493 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 318 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 494 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 495 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 319 | 496 | ||
| 320 | try comptime testExp(); | 497 | try testTan(f16); |
| 321 | try testExp(); | 498 | try comptime testTan(f16); |
| 322 | } | 499 | } |
| 323 | 500 | ||
| 324 | fn testExp() !void { | 501 | test "@tan f32/f64" { |
| 325 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 502 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 326 | const eps = epsForType(ty); | 503 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 327 | try expect(@exp(@as(ty, 0)) == 1); | 504 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 328 | try expect(math.approxEqAbs(ty, @exp(@as(ty, 2)), 7.389056098930650, eps)); | 505 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 329 | try expect(math.approxEqAbs(ty, @exp(@as(ty, 5)), 148.4131591025766, eps)); | 506 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 330 | } | 507 | |
| 508 | try testTan(f32); | ||
| 509 | try comptime testTan(f32); | ||
| 510 | try testTan(f64); | ||
| 511 | try comptime testTan(f64); | ||
| 512 | } | ||
| 513 | |||
| 514 | test "@tan f80/f128/c_longdouble" { | ||
| 515 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 516 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 517 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 518 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 519 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 520 | |||
| 521 | try testTan(f80); | ||
| 522 | try comptime testTan(f80); | ||
| 523 | try testTan(f128); | ||
| 524 | try comptime testTan(f128); | ||
| 525 | try testTan(c_longdouble); | ||
| 526 | try comptime testTan(c_longdouble); | ||
| 527 | } | ||
| 528 | |||
| 529 | fn testTan(comptime T: type) !void { | ||
| 530 | const eps = epsForType(T); | ||
| 531 | var zero: T = 0; | ||
| 532 | try expect(@tan(zero) == 0); | ||
| 533 | var pi: T = math.pi; | ||
| 534 | try expect(math.approxEqAbs(T, @tan(pi), 0, eps)); | ||
| 535 | try expect(math.approxEqAbs(T, @tan(pi / 3.0), 1.732050807568878, eps)); | ||
| 536 | try expect(math.approxEqAbs(T, @tan(pi / 4.0), 1, eps)); | ||
| 537 | } | ||
| 538 | |||
| 539 | test "@tan with vectors" { | ||
| 540 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 541 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 542 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 543 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 544 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 545 | |||
| 546 | try testTanWithVectors(); | ||
| 547 | try comptime testTanWithVectors(); | ||
| 548 | } | ||
| 549 | |||
| 550 | fn testTanWithVectors() !void { | ||
| 551 | var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | ||
| 552 | var result = @tan(v); | ||
| 553 | try expect(math.approxEqAbs(f32, @tan(@as(f32, 1.1)), result[0], epsilon)); | ||
| 554 | try expect(math.approxEqAbs(f32, @tan(@as(f32, 2.2)), result[1], epsilon)); | ||
| 555 | try expect(math.approxEqAbs(f32, @tan(@as(f32, 3.3)), result[2], epsilon)); | ||
| 556 | try expect(math.approxEqAbs(f32, @tan(@as(f32, 4.4)), result[3], epsilon)); | ||
| 557 | } | ||
| 558 | |||
| 559 | test "@exp f16" { | ||
| 560 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 561 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 562 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 563 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 564 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 565 | |||
| 566 | try testExp(f16); | ||
| 567 | try comptime testExp(f16); | ||
| 568 | } | ||
| 569 | |||
| 570 | test "@exp f32/f64" { | ||
| 571 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 572 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 573 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 574 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 575 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 576 | |||
| 577 | try testExp(f32); | ||
| 578 | try comptime testExp(f32); | ||
| 579 | try testExp(f64); | ||
| 580 | try comptime testExp(f64); | ||
| 581 | } | ||
| 582 | |||
| 583 | test "@exp f80/f128/c_longdouble" { | ||
| 584 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 585 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 586 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 587 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 588 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 589 | |||
| 590 | try testExp(f80); | ||
| 591 | try comptime testExp(f80); | ||
| 592 | try testExp(f128); | ||
| 593 | try comptime testExp(f128); | ||
| 594 | try testExp(c_longdouble); | ||
| 595 | try comptime testExp(c_longdouble); | ||
| 596 | } | ||
| 597 | |||
| 598 | fn testExp(comptime T: type) !void { | ||
| 599 | const eps = epsForType(T); | ||
| 600 | var zero: T = 0; | ||
| 601 | try expect(@exp(zero) == 1); | ||
| 602 | var two: T = 2; | ||
| 603 | try expect(math.approxEqAbs(T, @exp(two), 7.389056098930650, eps)); | ||
| 604 | var five: T = 5; | ||
| 605 | try expect(math.approxEqAbs(T, @exp(five), 148.4131591025766, eps)); | ||
| 331 | } | 606 | } |
| 332 | 607 | ||
| 333 | test "@exp with vectors" { | 608 | test "@exp with vectors" { |
| 334 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 609 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 335 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 336 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 610 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 337 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 611 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 338 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 612 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 613 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 339 | 614 | ||
| 340 | try comptime testExpWithVectors(); | ||
| 341 | try testExpWithVectors(); | 615 | try testExpWithVectors(); |
| 616 | try comptime testExpWithVectors(); | ||
| 342 | } | 617 | } |
| 343 | 618 | ||
| 344 | fn testExpWithVectors() !void { | 619 | fn testExpWithVectors() !void { |
| ... | @@ -350,35 +625,64 @@ fn testExpWithVectors() !void { | ... | @@ -350,35 +625,64 @@ fn testExpWithVectors() !void { |
| 350 | try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon)); | 625 | try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon)); |
| 351 | } | 626 | } |
| 352 | 627 | ||
| 353 | test "@exp2" { | 628 | test "@exp2 f16" { |
| 354 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 355 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 629 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 356 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 630 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 357 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 631 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 358 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 632 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 633 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 359 | 634 | ||
| 360 | try comptime testExp2(); | 635 | try testExp2(f16); |
| 361 | try testExp2(); | 636 | try comptime testExp2(f16); |
| 362 | } | 637 | } |
| 363 | 638 | ||
| 364 | fn testExp2() !void { | 639 | test "@exp2 f32/f64" { |
| 365 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 640 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 366 | const eps = epsForType(ty); | 641 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 367 | try expect(@exp2(@as(ty, 2)) == 4); | 642 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 368 | try expect(math.approxEqAbs(ty, @exp2(@as(ty, 1.5)), 2.8284271247462, eps)); | 643 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 369 | try expect(math.approxEqAbs(ty, @exp2(@as(ty, 4.5)), 22.627416997969, eps)); | 644 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 370 | } | 645 | |
| 646 | try testExp2(f32); | ||
| 647 | try comptime testExp2(f32); | ||
| 648 | try testExp2(f64); | ||
| 649 | try comptime testExp2(f64); | ||
| 650 | } | ||
| 651 | |||
| 652 | test "@exp2 f80/f128/c_longdouble" { | ||
| 653 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 654 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 655 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 656 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 657 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 658 | |||
| 659 | try testExp2(f80); | ||
| 660 | try comptime testExp2(f80); | ||
| 661 | try testExp2(f128); | ||
| 662 | try comptime testExp2(f128); | ||
| 663 | try testExp2(c_longdouble); | ||
| 664 | try comptime testExp2(c_longdouble); | ||
| 665 | } | ||
| 666 | |||
| 667 | fn testExp2(comptime T: type) !void { | ||
| 668 | const eps = epsForType(T); | ||
| 669 | var two: T = 2; | ||
| 670 | try expect(@exp2(two) == 4); | ||
| 671 | var one_point_five: T = 1.5; | ||
| 672 | try expect(math.approxEqAbs(T, @exp2(one_point_five), 2.8284271247462, eps)); | ||
| 673 | var four_point_five: T = 4.5; | ||
| 674 | try expect(math.approxEqAbs(T, @exp2(four_point_five), 22.627416997969, eps)); | ||
| 371 | } | 675 | } |
| 372 | 676 | ||
| 373 | test "@exp2 with @vectors" { | 677 | test "@exp2 with @vectors" { |
| 374 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 678 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 375 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 376 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 679 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 377 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 680 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 378 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 681 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 682 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 379 | 683 | ||
| 380 | try comptime testExp2WithVectors(); | ||
| 381 | try testExp2WithVectors(); | 684 | try testExp2WithVectors(); |
| 685 | try comptime testExp2WithVectors(); | ||
| 382 | } | 686 | } |
| 383 | 687 | ||
| 384 | fn testExp2WithVectors() !void { | 688 | fn testExp2WithVectors() !void { |
| ... | @@ -390,44 +694,62 @@ fn testExp2WithVectors() !void { | ... | @@ -390,44 +694,62 @@ fn testExp2WithVectors() !void { |
| 390 | try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon)); | 694 | try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon)); |
| 391 | } | 695 | } |
| 392 | 696 | ||
| 393 | test "@log" { | 697 | test "@log f16" { |
| 394 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 395 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 698 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 396 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 699 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 397 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 700 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 398 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 701 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 702 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 399 | 703 | ||
| 400 | try comptime testLog(); | 704 | try testLog(f16); |
| 401 | try testLog(); | 705 | try comptime testLog(f16); |
| 402 | } | 706 | } |
| 403 | 707 | ||
| 404 | fn testLog() !void { | 708 | test "@log f32/f64" { |
| 405 | { | 709 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 406 | var a: f16 = e; | 710 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 407 | try expect(math.approxEqAbs(f16, @log(a), 1, epsilon)); | 711 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 408 | } | 712 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 409 | { | 713 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 410 | var a: f32 = e; | 714 | |
| 411 | try expect(@log(a) == 1 or @log(a) == @as(f32, @bitCast(@as(u32, 0x3f7fffff)))); | 715 | try testLog(f32); |
| 412 | } | 716 | try comptime testLog(f32); |
| 413 | { | 717 | try testLog(f64); |
| 414 | var a: f64 = e; | 718 | try comptime testLog(f64); |
| 415 | try expect(@log(a) == 1 or @log(a) == @as(f64, @bitCast(@as(u64, 0x3ff0000000000000)))); | 719 | } |
| 416 | } | 720 | |
| 417 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 721 | test "@log f80/f128/c_longdouble" { |
| 418 | const eps = epsForType(ty); | 722 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 419 | try expect(math.approxEqAbs(ty, @log(@as(ty, 2)), 0.6931471805599, eps)); | 723 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 420 | try expect(math.approxEqAbs(ty, @log(@as(ty, 5)), 1.6094379124341, eps)); | 724 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 421 | } | 725 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 726 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 727 | |||
| 728 | try testLog(f80); | ||
| 729 | try comptime testLog(f80); | ||
| 730 | try testLog(f128); | ||
| 731 | try comptime testLog(f128); | ||
| 732 | try testLog(c_longdouble); | ||
| 733 | try comptime testLog(c_longdouble); | ||
| 734 | } | ||
| 735 | |||
| 736 | fn testLog(comptime T: type) !void { | ||
| 737 | const eps = epsForType(T); | ||
| 738 | var e: T = math.e; | ||
| 739 | try expect(math.approxEqAbs(T, @log(e), 1, eps)); | ||
| 740 | var two: T = 2; | ||
| 741 | try expect(math.approxEqAbs(T, @log(two), 0.6931471805599, eps)); | ||
| 742 | var five: T = 5; | ||
| 743 | try expect(math.approxEqAbs(T, @log(five), 1.6094379124341, eps)); | ||
| 422 | } | 744 | } |
| 423 | 745 | ||
| 424 | test "@log with @vectors" { | 746 | test "@log with @vectors" { |
| 425 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 747 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 426 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 427 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 748 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 428 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 749 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 429 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 750 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 430 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 751 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 752 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 431 | 753 | ||
| 432 | { | 754 | { |
| 433 | var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | 755 | var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; |
| ... | @@ -439,29 +761,57 @@ test "@log with @vectors" { | ... | @@ -439,29 +761,57 @@ test "@log with @vectors" { |
| 439 | } | 761 | } |
| 440 | } | 762 | } |
| 441 | 763 | ||
| 442 | test "@log2" { | 764 | test "@log2 f16" { |
| 443 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 444 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 765 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 445 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 766 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 446 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 767 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 447 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 768 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 769 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 448 | 770 | ||
| 449 | try comptime testLog2(); | 771 | try testLog2(f16); |
| 450 | try testLog2(); | 772 | try comptime testLog2(f16); |
| 451 | } | 773 | } |
| 452 | 774 | ||
| 453 | fn testLog2() !void { | 775 | test "@log2 f32/f64" { |
| 454 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 776 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 455 | const eps = epsForType(ty); | 777 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 456 | try expect(@log2(@as(ty, 4)) == 2); | 778 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 457 | try expect(math.approxEqAbs(ty, @log2(@as(ty, 6)), 2.5849625007212, eps)); | 779 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 458 | try expect(math.approxEqAbs(ty, @log2(@as(ty, 10)), 3.3219280948874, eps)); | 780 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 459 | } | 781 | |
| 782 | try testLog2(f32); | ||
| 783 | try comptime testLog2(f32); | ||
| 784 | try testLog2(f64); | ||
| 785 | try comptime testLog2(f64); | ||
| 786 | } | ||
| 787 | |||
| 788 | test "@log2 f80/f128/c_longdouble" { | ||
| 789 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 790 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 791 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 792 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 793 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 794 | |||
| 795 | try testLog2(f80); | ||
| 796 | try comptime testLog2(f80); | ||
| 797 | try testLog2(f128); | ||
| 798 | try comptime testLog2(f128); | ||
| 799 | try testLog2(c_longdouble); | ||
| 800 | try comptime testLog2(c_longdouble); | ||
| 801 | } | ||
| 802 | |||
| 803 | fn testLog2(comptime T: type) !void { | ||
| 804 | const eps = epsForType(T); | ||
| 805 | var four: T = 4; | ||
| 806 | try expect(@log2(four) == 2); | ||
| 807 | var six: T = 6; | ||
| 808 | try expect(math.approxEqAbs(T, @log2(six), 2.5849625007212, eps)); | ||
| 809 | var ten: T = 10; | ||
| 810 | try expect(math.approxEqAbs(T, @log2(ten), 3.3219280948874, eps)); | ||
| 460 | } | 811 | } |
| 461 | 812 | ||
| 462 | test "@log2 with vectors" { | 813 | test "@log2 with vectors" { |
| 463 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 814 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 464 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 465 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 815 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 466 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 816 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 467 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 817 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| ... | @@ -469,9 +819,10 @@ test "@log2 with vectors" { | ... | @@ -469,9 +819,10 @@ test "@log2 with vectors" { |
| 469 | if (builtin.zig_backend == .stage2_llvm and | 819 | if (builtin.zig_backend == .stage2_llvm and |
| 470 | builtin.cpu.arch == .aarch64 and | 820 | builtin.cpu.arch == .aarch64 and |
| 471 | builtin.os.tag == .windows) return error.SkipZigTest; | 821 | builtin.os.tag == .windows) return error.SkipZigTest; |
| 822 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 472 | 823 | ||
| 473 | try comptime testLog2WithVectors(); | ||
| 474 | try testLog2WithVectors(); | 824 | try testLog2WithVectors(); |
| 825 | try comptime testLog2WithVectors(); | ||
| 475 | } | 826 | } |
| 476 | 827 | ||
| 477 | fn testLog2WithVectors() !void { | 828 | fn testLog2WithVectors() !void { |
| ... | @@ -483,35 +834,64 @@ fn testLog2WithVectors() !void { | ... | @@ -483,35 +834,64 @@ fn testLog2WithVectors() !void { |
| 483 | try expect(@log2(@as(f32, 0.4)) == result[3]); | 834 | try expect(@log2(@as(f32, 0.4)) == result[3]); |
| 484 | } | 835 | } |
| 485 | 836 | ||
| 486 | test "@log10" { | 837 | test "@log10 f16" { |
| 487 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 488 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 838 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 489 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 839 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 490 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 840 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 491 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 841 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 842 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 492 | 843 | ||
| 493 | try comptime testLog10(); | 844 | try testLog10(f16); |
| 494 | try testLog10(); | 845 | try comptime testLog10(f16); |
| 495 | } | 846 | } |
| 496 | 847 | ||
| 497 | fn testLog10() !void { | 848 | test "@log10 f32/f64" { |
| 498 | inline for ([_]type{ f16, f32, f64 }) |ty| { | 849 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 499 | const eps = epsForType(ty); | 850 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 500 | try expect(@log10(@as(ty, 100)) == 2); | 851 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 501 | try expect(math.approxEqAbs(ty, @log10(@as(ty, 15)), 1.176091259056, eps)); | 852 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 502 | try expect(math.approxEqAbs(ty, @log10(@as(ty, 50)), 1.698970004336, eps)); | 853 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 503 | } | 854 | |
| 855 | try testLog10(f32); | ||
| 856 | try comptime testLog10(f32); | ||
| 857 | try testLog10(f64); | ||
| 858 | try comptime testLog10(f64); | ||
| 859 | } | ||
| 860 | |||
| 861 | test "@log10 f80/f128/c_longdouble" { | ||
| 862 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 863 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 864 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 865 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 866 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 867 | |||
| 868 | try testLog10(f80); | ||
| 869 | try comptime testLog10(f80); | ||
| 870 | try testLog10(f128); | ||
| 871 | try comptime testLog10(f128); | ||
| 872 | try testLog10(c_longdouble); | ||
| 873 | try comptime testLog10(c_longdouble); | ||
| 874 | } | ||
| 875 | |||
| 876 | fn testLog10(comptime T: type) !void { | ||
| 877 | const eps = epsForType(T); | ||
| 878 | var hundred: T = 100; | ||
| 879 | try expect(@log10(hundred) == 2); | ||
| 880 | var fifteen: T = 15; | ||
| 881 | try expect(math.approxEqAbs(T, @log10(fifteen), 1.176091259056, eps)); | ||
| 882 | var fifty: T = 50; | ||
| 883 | try expect(math.approxEqAbs(T, @log10(fifty), 1.698970004336, eps)); | ||
| 504 | } | 884 | } |
| 505 | 885 | ||
| 506 | test "@log10 with vectors" { | 886 | test "@log10 with vectors" { |
| 507 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 887 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 508 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 509 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 888 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 510 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 889 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 511 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 890 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 891 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 512 | 892 | ||
| 513 | try comptime testLog10WithVectors(); | ||
| 514 | try testLog10WithVectors(); | 893 | try testLog10WithVectors(); |
| 894 | try comptime testLog10WithVectors(); | ||
| 515 | } | 895 | } |
| 516 | 896 | ||
| 517 | fn testLog10WithVectors() !void { | 897 | fn testLog10WithVectors() !void { |
| ... | @@ -523,41 +903,94 @@ fn testLog10WithVectors() !void { | ... | @@ -523,41 +903,94 @@ fn testLog10WithVectors() !void { |
| 523 | try expect(@log10(@as(f32, 0.4)) == result[3]); | 903 | try expect(@log10(@as(f32, 0.4)) == result[3]); |
| 524 | } | 904 | } |
| 525 | 905 | ||
| 526 | test "@abs" { | 906 | test "@abs f16" { |
| 527 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 907 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 528 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 908 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 529 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 909 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 910 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 530 | 911 | ||
| 531 | try comptime testFabs(); | 912 | try testFabs(f16); |
| 532 | try testFabs(); | 913 | try comptime testFabs(f16); |
| 533 | } | 914 | } |
| 534 | 915 | ||
| 535 | fn testFabs() !void { | 916 | test "@abs f32/f64" { |
| 536 | try expect(@abs(@as(f16, -2.5)) == 2.5); | 917 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 537 | try expect(@abs(@as(f16, 2.5)) == 2.5); | 918 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 538 | try expect(@abs(@as(f32, -2.5)) == 2.5); | 919 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 539 | try expect(@abs(@as(f32, 2.5)) == 2.5); | ||
| 540 | try expect(@abs(@as(f64, -2.5)) == 2.5); | ||
| 541 | try expect(@abs(@as(f64, 2.5)) == 2.5); | ||
| 542 | 920 | ||
| 543 | // TODO test f128, and c_longdouble | 921 | try testFabs(f32); |
| 544 | // https://github.com/ziglang/zig/issues/4026 | 922 | try comptime testFabs(f32); |
| 545 | // { | 923 | try testFabs(f64); |
| 546 | // var a: f80 = -2.5; | 924 | try comptime testFabs(f64); |
| 547 | // var b: f80 = 2.5; | ||
| 548 | // try expect(@abs(a) == 2.5); | ||
| 549 | // try expect(@abs(b) == 2.5); | ||
| 550 | // } | ||
| 551 | } | 925 | } |
| 552 | 926 | ||
| 553 | test "@abs with vectors" { | 927 | test "@abs f80/f128/c_longdouble" { |
| 554 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 555 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 928 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 556 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 929 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 930 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 931 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 932 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 933 | |||
| 934 | try testFabs(f80); | ||
| 935 | try comptime testFabs(f80); | ||
| 936 | try testFabs(f128); | ||
| 937 | try comptime testFabs(f128); | ||
| 938 | try testFabs(c_longdouble); | ||
| 939 | try comptime testFabs(c_longdouble); | ||
| 940 | } | ||
| 941 | |||
| 942 | fn testFabs(comptime T: type) !void { | ||
| 943 | var two_point_five: T = 2.5; | ||
| 944 | try expect(@abs(two_point_five) == 2.5); | ||
| 945 | var neg_two_point_five: T = -2.5; | ||
| 946 | try expect(@abs(neg_two_point_five) == 2.5); | ||
| 947 | |||
| 948 | var twelve: T = 12.0; | ||
| 949 | try expect(@abs(twelve) == 12.0); | ||
| 950 | var neg_fourteen: T = -14.0; | ||
| 951 | try expect(@abs(neg_fourteen) == 14.0); | ||
| 952 | |||
| 953 | // normals | ||
| 954 | var one: T = 1.0; | ||
| 955 | try expect(@abs(one) == 1.0); | ||
| 956 | var neg_one: T = -1.0; | ||
| 957 | try expect(@abs(neg_one) == 1.0); | ||
| 958 | var min: T = math.floatMin(T); | ||
| 959 | try expect(@abs(min) == math.floatMin(T)); | ||
| 960 | var neg_min: T = -math.floatMin(T); | ||
| 961 | try expect(@abs(neg_min) == math.floatMin(T)); | ||
| 962 | var max: T = math.floatMax(T); | ||
| 963 | try expect(@abs(max) == math.floatMax(T)); | ||
| 964 | var neg_max: T = -math.floatMax(T); | ||
| 965 | try expect(@abs(neg_max) == math.floatMax(T)); | ||
| 966 | |||
| 967 | // subnormals | ||
| 968 | var zero: T = 0.0; | ||
| 969 | try expect(@abs(zero) == 0.0); | ||
| 970 | var neg_zero: T = -0.0; | ||
| 971 | try expect(@abs(neg_zero) == 0.0); | ||
| 972 | var true_min: T = math.floatTrueMin(T); | ||
| 973 | try expect(@abs(true_min) == math.floatTrueMin(T)); | ||
| 974 | var neg_true_min: T = -math.floatTrueMin(T); | ||
| 975 | try expect(@abs(neg_true_min) == math.floatTrueMin(T)); | ||
| 976 | |||
| 977 | // non-finite numbers | ||
| 978 | var inf: T = math.inf(T); | ||
| 979 | try expect(math.isPositiveInf(@abs(inf))); | ||
| 980 | var neg_inf: T = -math.inf(T); | ||
| 981 | try expect(math.isPositiveInf(@abs(neg_inf))); | ||
| 982 | var nan: T = math.nan(T); | ||
| 983 | try expect(math.isNan(@abs(nan))); | ||
| 984 | } | ||
| 985 | |||
| 986 | test "@abs with vectors" { | ||
| 987 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 988 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 557 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 989 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 990 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 558 | 991 | ||
| 559 | try comptime testFabsWithVectors(); | ||
| 560 | try testFabsWithVectors(); | 992 | try testFabsWithVectors(); |
| 993 | try comptime testFabsWithVectors(); | ||
| 561 | } | 994 | } |
| 562 | 995 | ||
| 563 | fn testFabsWithVectors() !void { | 996 | fn testFabsWithVectors() !void { |
| ... | @@ -569,109 +1002,77 @@ fn testFabsWithVectors() !void { | ... | @@ -569,109 +1002,77 @@ fn testFabsWithVectors() !void { |
| 569 | try expect(math.approxEqAbs(f32, @abs(@as(f32, -0.4)), result[3], epsilon)); | 1002 | try expect(math.approxEqAbs(f32, @abs(@as(f32, -0.4)), result[3], epsilon)); |
| 570 | } | 1003 | } |
| 571 | 1004 | ||
| 572 | test "another, possibly redundant, @abs test" { | 1005 | test "@floor f16" { |
| 573 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 574 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 575 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1006 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 576 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1007 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 577 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1008 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 578 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 1009 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 579 | |||
| 580 | try testFabsLegacy(f128, 12.0); | ||
| 581 | try comptime testFabsLegacy(f128, 12.0); | ||
| 582 | try testFabsLegacy(f64, 12.0); | ||
| 583 | try comptime testFabsLegacy(f64, 12.0); | ||
| 584 | try testFabsLegacy(f32, 12.0); | ||
| 585 | try comptime testFabsLegacy(f32, 12.0); | ||
| 586 | try testFabsLegacy(f16, 12.0); | ||
| 587 | try comptime testFabsLegacy(f16, 12.0); | ||
| 588 | 1010 | ||
| 589 | const x = 14.0; | 1011 | try testFloor(f16); |
| 590 | const y = -x; | 1012 | try comptime testFloor(f16); |
| 591 | const z = @abs(y); | ||
| 592 | try comptime std.testing.expectEqual(x, z); | ||
| 593 | } | 1013 | } |
| 594 | 1014 | ||
| 595 | test "@abs f80" { | 1015 | test "@floor f32/f64" { |
| 596 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 597 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 598 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1016 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 599 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1017 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 600 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1018 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 601 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 1019 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 602 | |||
| 603 | try testFabsLegacy(f80, 12.0); | ||
| 604 | try comptime testFabsLegacy(f80, 12.0); | ||
| 605 | } | ||
| 606 | 1020 | ||
| 607 | fn testFabsLegacy(comptime T: type, x: T) !void { | 1021 | try testFloor(f32); |
| 608 | const y = -x; | 1022 | try comptime testFloor(f32); |
| 609 | const z = @abs(y); | 1023 | try testFloor(f64); |
| 610 | try expect(x == z); | 1024 | try comptime testFloor(f64); |
| 611 | } | 1025 | } |
| 612 | 1026 | ||
| 613 | test "a third @abs test, surely there should not be three fabs tests" { | 1027 | test "@floor f80/f128/c_longdouble" { |
| 614 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 615 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 616 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1028 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 617 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 618 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 619 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 620 | |||
| 621 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { | ||
| 622 | // normals | ||
| 623 | try expect(@abs(@as(T, 1.0)) == 1.0); | ||
| 624 | try expect(@abs(@as(T, -1.0)) == 1.0); | ||
| 625 | try expect(@abs(math.floatMin(T)) == math.floatMin(T)); | ||
| 626 | try expect(@abs(-math.floatMin(T)) == math.floatMin(T)); | ||
| 627 | try expect(@abs(math.floatMax(T)) == math.floatMax(T)); | ||
| 628 | try expect(@abs(-math.floatMax(T)) == math.floatMax(T)); | ||
| 629 | |||
| 630 | // subnormals | ||
| 631 | try expect(@abs(@as(T, 0.0)) == 0.0); | ||
| 632 | try expect(@abs(@as(T, -0.0)) == 0.0); | ||
| 633 | try expect(@abs(math.floatTrueMin(T)) == math.floatTrueMin(T)); | ||
| 634 | try expect(@abs(-math.floatTrueMin(T)) == math.floatTrueMin(T)); | ||
| 635 | |||
| 636 | // non-finite numbers | ||
| 637 | try expect(math.isPositiveInf(@abs(math.inf(T)))); | ||
| 638 | try expect(math.isPositiveInf(@abs(-math.inf(T)))); | ||
| 639 | try expect(math.isNan(@abs(math.nan(T)))); | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | test "@floor" { | ||
| 644 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1029 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 645 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1030 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| 646 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1031 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1032 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 647 | 1033 | ||
| 648 | try comptime testFloor(); | 1034 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 649 | try testFloor(); | 1035 | // https://github.com/ziglang/zig/issues/12602 |
| 650 | } | 1036 | return error.SkipZigTest; |
| 651 | 1037 | } | |
| 652 | fn testFloor() !void { | ||
| 653 | try expect(@floor(@as(f16, 2.1)) == 2); | ||
| 654 | try expect(@floor(@as(f32, 2.1)) == 2); | ||
| 655 | try expect(@floor(@as(f64, 3.5)) == 3); | ||
| 656 | 1038 | ||
| 657 | // TODO test f128, and c_longdouble | 1039 | try testFloor(f80); |
| 658 | // https://github.com/ziglang/zig/issues/4026 | 1040 | try comptime testFloor(f80); |
| 659 | // { | 1041 | try testFloor(f128); |
| 660 | // var a: f80 = 3.5; | 1042 | try comptime testFloor(f128); |
| 661 | // try expect(@floor(a) == 3); | 1043 | try testFloor(c_longdouble); |
| 662 | // } | 1044 | try comptime testFloor(c_longdouble); |
| 1045 | } | ||
| 1046 | |||
| 1047 | fn testFloor(comptime T: type) !void { | ||
| 1048 | var two_point_one: T = 2.1; | ||
| 1049 | try expect(@floor(two_point_one) == 2.0); | ||
| 1050 | var neg_two_point_one: T = -2.1; | ||
| 1051 | try expect(@floor(neg_two_point_one) == -3.0); | ||
| 1052 | var three_point_five: T = 3.5; | ||
| 1053 | try expect(@floor(three_point_five) == 3.0); | ||
| 1054 | var neg_three_point_five: T = -3.5; | ||
| 1055 | try expect(@floor(neg_three_point_five) == -4.0); | ||
| 1056 | var twelve: T = 12.0; | ||
| 1057 | try expect(@floor(twelve) == 12.0); | ||
| 1058 | var neg_twelve: T = -12.0; | ||
| 1059 | try expect(@floor(neg_twelve) == -12.0); | ||
| 1060 | var fourteen_point_seven: T = 14.7; | ||
| 1061 | try expect(@floor(fourteen_point_seven) == 14.0); | ||
| 1062 | var neg_fourteen_point_seven: T = -14.7; | ||
| 1063 | try expect(@floor(neg_fourteen_point_seven) == -15.0); | ||
| 663 | } | 1064 | } |
| 664 | 1065 | ||
| 665 | test "@floor with vectors" { | 1066 | test "@floor with vectors" { |
| 666 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 667 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 668 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 669 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 670 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1067 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1068 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 671 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1069 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1070 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1071 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 1072 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 672 | 1073 | ||
| 673 | try comptime testFloorWithVectors(); | ||
| 674 | try testFloorWithVectors(); | 1074 | try testFloorWithVectors(); |
| 1075 | try comptime testFloorWithVectors(); | ||
| 675 | } | 1076 | } |
| 676 | 1077 | ||
| 677 | fn testFloorWithVectors() !void { | 1078 | fn testFloorWithVectors() !void { |
| ... | @@ -683,90 +1084,77 @@ fn testFloorWithVectors() !void { | ... | @@ -683,90 +1084,77 @@ fn testFloorWithVectors() !void { |
| 683 | try expect(math.approxEqAbs(f32, @floor(@as(f32, -0.4)), result[3], epsilon)); | 1084 | try expect(math.approxEqAbs(f32, @floor(@as(f32, -0.4)), result[3], epsilon)); |
| 684 | } | 1085 | } |
| 685 | 1086 | ||
| 686 | test "another, possibly redundant, @floor test" { | 1087 | test "@ceil f16" { |
| 687 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 688 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1088 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 689 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 690 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 691 | |||
| 692 | try testFloorLegacy(f64, 12.0); | ||
| 693 | try comptime testFloorLegacy(f64, 12.0); | ||
| 694 | try testFloorLegacy(f32, 12.0); | ||
| 695 | try comptime testFloorLegacy(f32, 12.0); | ||
| 696 | try testFloorLegacy(f16, 12.0); | ||
| 697 | try comptime testFloorLegacy(f16, 12.0); | ||
| 698 | |||
| 699 | const x = 14.0; | ||
| 700 | const y = x + 0.7; | ||
| 701 | const z = @floor(y); | ||
| 702 | try comptime expect(x == z); | ||
| 703 | } | ||
| 704 | |||
| 705 | test "@floor f80" { | ||
| 706 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1089 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 707 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1090 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 708 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1091 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 709 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 710 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 711 | |||
| 712 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 713 | // https://github.com/ziglang/zig/issues/12602 | ||
| 714 | return error.SkipZigTest; | ||
| 715 | } | ||
| 716 | 1092 | ||
| 717 | try testFloorLegacy(f80, 12.0); | 1093 | try testCeil(f16); |
| 718 | try comptime testFloorLegacy(f80, 12.0); | 1094 | try comptime testCeil(f16); |
| 719 | } | 1095 | } |
| 720 | 1096 | ||
| 721 | test "@floor f128" { | 1097 | test "@ceil f32/f64" { |
| 722 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 723 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1098 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 724 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1099 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 725 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1100 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 726 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 1101 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 727 | |||
| 728 | try testFloorLegacy(f128, 12.0); | ||
| 729 | try comptime testFloorLegacy(f128, 12.0); | ||
| 730 | } | ||
| 731 | 1102 | ||
| 732 | fn testFloorLegacy(comptime T: type, x: T) !void { | 1103 | try testCeil(f32); |
| 733 | const y = x + 0.6; | 1104 | try comptime testCeil(f32); |
| 734 | const z = @floor(y); | 1105 | try testCeil(f64); |
| 735 | try expect(x == z); | 1106 | try comptime testCeil(f64); |
| 736 | } | 1107 | } |
| 737 | 1108 | ||
| 738 | test "@ceil" { | 1109 | test "@ceil f80/f128/c_longdouble" { |
| 739 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 740 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1110 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1111 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1112 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 741 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1113 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1114 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 742 | 1115 | ||
| 743 | try comptime testCeil(); | 1116 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 744 | try testCeil(); | 1117 | // https://github.com/ziglang/zig/issues/12602 |
| 745 | } | 1118 | return error.SkipZigTest; |
| 746 | 1119 | } | |
| 747 | fn testCeil() !void { | ||
| 748 | try expect(@ceil(@as(f16, 2.1)) == 3); | ||
| 749 | try expect(@ceil(@as(f32, 2.1)) == 3); | ||
| 750 | try expect(@ceil(@as(f64, 3.5)) == 4); | ||
| 751 | 1120 | ||
| 752 | // TODO test f128, and c_longdouble | 1121 | try testCeil(f80); |
| 753 | // https://github.com/ziglang/zig/issues/4026 | 1122 | try comptime testCeil(f80); |
| 754 | // { | 1123 | try testCeil(f128); |
| 755 | // var a: f80 = 3.5; | 1124 | try comptime testCeil(f128); |
| 756 | // try expect(@ceil(a) == 4); | 1125 | try testCeil(c_longdouble); |
| 757 | // } | 1126 | try comptime testCeil(c_longdouble); |
| 1127 | } | ||
| 1128 | |||
| 1129 | fn testCeil(comptime T: type) !void { | ||
| 1130 | var two_point_one: T = 2.1; | ||
| 1131 | try expect(@ceil(two_point_one) == 3.0); | ||
| 1132 | var neg_two_point_one: T = -2.1; | ||
| 1133 | try expect(@ceil(neg_two_point_one) == -2.0); | ||
| 1134 | var three_point_five: T = 3.5; | ||
| 1135 | try expect(@ceil(three_point_five) == 4.0); | ||
| 1136 | var neg_three_point_five: T = -3.5; | ||
| 1137 | try expect(@ceil(neg_three_point_five) == -3.0); | ||
| 1138 | var twelve: T = 12.0; | ||
| 1139 | try expect(@ceil(twelve) == 12.0); | ||
| 1140 | var neg_twelve: T = -12.0; | ||
| 1141 | try expect(@ceil(neg_twelve) == -12.0); | ||
| 1142 | var fourteen_point_seven: T = 14.7; | ||
| 1143 | try expect(@ceil(fourteen_point_seven) == 15.0); | ||
| 1144 | var neg_fourteen_point_seven: T = -14.7; | ||
| 1145 | try expect(@ceil(neg_fourteen_point_seven) == -14.0); | ||
| 758 | } | 1146 | } |
| 759 | 1147 | ||
| 760 | test "@ceil with vectors" { | 1148 | test "@ceil with vectors" { |
| 761 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 762 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 763 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 764 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 765 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1150 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 766 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1151 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1152 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1153 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 1154 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 767 | 1155 | ||
| 768 | try comptime testCeilWithVectors(); | ||
| 769 | try testCeilWithVectors(); | 1156 | try testCeilWithVectors(); |
| 1157 | try comptime testCeilWithVectors(); | ||
| 770 | } | 1158 | } |
| 771 | 1159 | ||
| 772 | fn testCeilWithVectors() !void { | 1160 | fn testCeilWithVectors() !void { |
| ... | @@ -778,90 +1166,87 @@ fn testCeilWithVectors() !void { | ... | @@ -778,90 +1166,87 @@ fn testCeilWithVectors() !void { |
| 778 | try expect(math.approxEqAbs(f32, @ceil(@as(f32, -0.4)), result[3], epsilon)); | 1166 | try expect(math.approxEqAbs(f32, @ceil(@as(f32, -0.4)), result[3], epsilon)); |
| 779 | } | 1167 | } |
| 780 | 1168 | ||
| 781 | test "another, possibly redundant, @ceil test" { | 1169 | test "@trunc f16" { |
| 782 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 783 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 784 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 785 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 786 | |||
| 787 | try testCeilLegacy(f64, 12.0); | ||
| 788 | try comptime testCeilLegacy(f64, 12.0); | ||
| 789 | try testCeilLegacy(f32, 12.0); | ||
| 790 | try comptime testCeilLegacy(f32, 12.0); | ||
| 791 | try testCeilLegacy(f16, 12.0); | ||
| 792 | try comptime testCeilLegacy(f16, 12.0); | ||
| 793 | |||
| 794 | const x = 14.0; | ||
| 795 | const y = x - 0.7; | ||
| 796 | const z = @ceil(y); | ||
| 797 | try comptime expect(x == z); | ||
| 798 | } | ||
| 799 | |||
| 800 | test "@ceil f80" { | ||
| 801 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1171 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 802 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1172 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 803 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1173 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 804 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 805 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 806 | 1174 | ||
| 807 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | 1175 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) { |
| 808 | // https://github.com/ziglang/zig/issues/12602 | 1176 | // https://github.com/ziglang/zig/issues/16846 |
| 809 | return error.SkipZigTest; | 1177 | return error.SkipZigTest; |
| 810 | } | 1178 | } |
| 811 | 1179 | ||
| 812 | try testCeilLegacy(f80, 12.0); | 1180 | try testTrunc(f16); |
| 813 | try comptime testCeilLegacy(f80, 12.0); | 1181 | try comptime testTrunc(f16); |
| 814 | } | 1182 | } |
| 815 | 1183 | ||
| 816 | test "@ceil f128" { | 1184 | test "@trunc f32/f64" { |
| 817 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 818 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1185 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 819 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1186 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 820 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1187 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 821 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 1188 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 822 | 1189 | ||
| 823 | try testCeilLegacy(f128, 12.0); | 1190 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) { |
| 824 | try comptime testCeilLegacy(f128, 12.0); | 1191 | // https://github.com/ziglang/zig/issues/16846 |
| 825 | } | 1192 | return error.SkipZigTest; |
| 1193 | } | ||
| 826 | 1194 | ||
| 827 | fn testCeilLegacy(comptime T: type, x: T) !void { | 1195 | try testTrunc(f32); |
| 828 | const y = x - 0.8; | 1196 | try comptime testTrunc(f32); |
| 829 | const z = @ceil(y); | 1197 | try testTrunc(f64); |
| 830 | try expect(x == z); | 1198 | try comptime testTrunc(f64); |
| 831 | } | 1199 | } |
| 832 | 1200 | ||
| 833 | test "@trunc" { | 1201 | test "@trunc f80/f128/c_longdouble" { |
| 834 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 835 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1202 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1203 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1204 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 836 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1205 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1206 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 837 | 1207 | ||
| 838 | try comptime testTrunc(); | 1208 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { |
| 839 | try testTrunc(); | 1209 | // https://github.com/ziglang/zig/issues/12602 |
| 840 | } | 1210 | return error.SkipZigTest; |
| 841 | 1211 | } | |
| 842 | fn testTrunc() !void { | ||
| 843 | try expect(@trunc(@as(f16, 2.1)) == 2); | ||
| 844 | try expect(@trunc(@as(f32, 2.1)) == 2); | ||
| 845 | try expect(@trunc(@as(f64, -3.5)) == -3); | ||
| 846 | 1212 | ||
| 847 | // TODO test f128, and c_longdouble | 1213 | try testTrunc(f80); |
| 848 | // https://github.com/ziglang/zig/issues/4026 | 1214 | try comptime testTrunc(f80); |
| 849 | // { | 1215 | try testTrunc(f128); |
| 850 | // var a: f80 = -3.5; | 1216 | try comptime testTrunc(f128); |
| 851 | // try expect(@trunc(a) == -3); | 1217 | try testTrunc(c_longdouble); |
| 852 | // } | 1218 | try comptime testTrunc(c_longdouble); |
| 1219 | } | ||
| 1220 | |||
| 1221 | fn testTrunc(comptime T: type) !void { | ||
| 1222 | var two_point_one: T = 2.1; | ||
| 1223 | try expect(@trunc(two_point_one) == 2.0); | ||
| 1224 | var neg_two_point_one: T = -2.1; | ||
| 1225 | try expect(@trunc(neg_two_point_one) == -2.0); | ||
| 1226 | var three_point_five: T = 3.5; | ||
| 1227 | try expect(@trunc(three_point_five) == 3.0); | ||
| 1228 | var neg_three_point_five: T = -3.5; | ||
| 1229 | try expect(@trunc(neg_three_point_five) == -3.0); | ||
| 1230 | var twelve: T = 12.0; | ||
| 1231 | try expect(@trunc(twelve) == 12.0); | ||
| 1232 | var neg_twelve: T = -12.0; | ||
| 1233 | try expect(@trunc(neg_twelve) == -12.0); | ||
| 1234 | var fourteen_point_seven: T = 14.7; | ||
| 1235 | try expect(@trunc(fourteen_point_seven) == 14.0); | ||
| 1236 | var neg_fourteen_point_seven: T = -14.7; | ||
| 1237 | try expect(@trunc(neg_fourteen_point_seven) == -14.0); | ||
| 853 | } | 1238 | } |
| 854 | 1239 | ||
| 855 | test "@trunc with vectors" { | 1240 | test "@trunc with vectors" { |
| 856 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 857 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 858 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 859 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 860 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1241 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1242 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 861 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1243 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1244 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1245 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 1246 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; | ||
| 862 | 1247 | ||
| 863 | try comptime testTruncWithVectors(); | ||
| 864 | try testTruncWithVectors(); | 1248 | try testTruncWithVectors(); |
| 1249 | try comptime testTruncWithVectors(); | ||
| 865 | } | 1250 | } |
| 866 | 1251 | ||
| 867 | fn testTruncWithVectors() !void { | 1252 | fn testTruncWithVectors() !void { |
| ... | @@ -873,183 +1258,98 @@ fn testTruncWithVectors() !void { | ... | @@ -873,183 +1258,98 @@ fn testTruncWithVectors() !void { |
| 873 | try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); | 1258 | try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); |
| 874 | } | 1259 | } |
| 875 | 1260 | ||
| 876 | test "another, possibly redundant, @trunc test" { | 1261 | test "neg f16" { |
| 877 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 878 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1262 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 879 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 880 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 881 | |||
| 882 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) { | ||
| 883 | // https://github.com/ziglang/zig/issues/16846 | ||
| 884 | return error.SkipZigTest; | ||
| 885 | } | ||
| 886 | |||
| 887 | try testTruncLegacy(f64, 12.0); | ||
| 888 | try comptime testTruncLegacy(f64, 12.0); | ||
| 889 | try testTruncLegacy(f32, 12.0); | ||
| 890 | try comptime testTruncLegacy(f32, 12.0); | ||
| 891 | try testTruncLegacy(f16, 12.0); | ||
| 892 | try comptime testTruncLegacy(f16, 12.0); | ||
| 893 | |||
| 894 | const x = 14.0; | ||
| 895 | const y = x + 0.7; | ||
| 896 | const z = @trunc(y); | ||
| 897 | try comptime expect(x == z); | ||
| 898 | } | ||
| 899 | |||
| 900 | test "@trunc f80" { | ||
| 901 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 902 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 903 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 904 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 905 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 906 | |||
| 907 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { | ||
| 908 | // https://github.com/ziglang/zig/issues/12602 | ||
| 909 | return error.SkipZigTest; | ||
| 910 | } | ||
| 911 | |||
| 912 | try testTruncLegacy(f80, 12.0); | ||
| 913 | try comptime testTruncLegacy(f80, 12.0); | ||
| 914 | comptime { | ||
| 915 | const x: f80 = 12.0; | ||
| 916 | const y = x + 0.8; | ||
| 917 | const z = @trunc(y); | ||
| 918 | try expect(x == z); | ||
| 919 | } | ||
| 920 | } | ||
| 921 | |||
| 922 | test "@trunc f128" { | ||
| 923 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 924 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 925 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 926 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 927 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | ||
| 928 | |||
| 929 | try testTruncLegacy(f128, 12.0); | ||
| 930 | try comptime testTruncLegacy(f128, 12.0); | ||
| 931 | } | ||
| 932 | |||
| 933 | fn testTruncLegacy(comptime T: type, x: T) !void { | ||
| 934 | { | ||
| 935 | const y = x + 0.8; | ||
| 936 | const z = @trunc(y); | ||
| 937 | try expect(x == z); | ||
| 938 | } | ||
| 939 | |||
| 940 | { | ||
| 941 | const y = -x - 0.8; | ||
| 942 | const z = @trunc(y); | ||
| 943 | try expect(-x == z); | ||
| 944 | } | ||
| 945 | } | ||
| 946 | |||
| 947 | test "negation f16" { | ||
| 948 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 949 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1263 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 950 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 951 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1264 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 952 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1265 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1266 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 1267 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 953 | 1268 | ||
| 954 | if (builtin.os.tag == .freebsd) { | 1269 | if (builtin.os.tag == .freebsd) { |
| 955 | // TODO file issue to track this failure | 1270 | // TODO file issue to track this failure |
| 956 | return error.SkipZigTest; | 1271 | return error.SkipZigTest; |
| 957 | } | 1272 | } |
| 958 | 1273 | ||
| 959 | const S = struct { | 1274 | try testNeg(f16); |
| 960 | fn doTheTest() !void { | 1275 | try comptime testNeg(f16); |
| 961 | var a: f16 = 1; | ||
| 962 | a = -a; | ||
| 963 | try expect(a == -1); | ||
| 964 | a = -a; | ||
| 965 | try expect(a == 1); | ||
| 966 | } | ||
| 967 | }; | ||
| 968 | |||
| 969 | try S.doTheTest(); | ||
| 970 | try comptime S.doTheTest(); | ||
| 971 | } | 1276 | } |
| 972 | 1277 | ||
| 973 | test "negation f32" { | 1278 | test "neg f32/f64" { |
| 974 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 975 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1279 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 976 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 977 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 978 | |||
| 979 | const S = struct { | ||
| 980 | fn doTheTest() !void { | ||
| 981 | var a: f32 = 1; | ||
| 982 | a = -a; | ||
| 983 | try expect(a == -1); | ||
| 984 | a = -a; | ||
| 985 | try expect(a == 1); | ||
| 986 | } | ||
| 987 | }; | ||
| 988 | |||
| 989 | try S.doTheTest(); | ||
| 990 | try comptime S.doTheTest(); | ||
| 991 | } | ||
| 992 | |||
| 993 | test "negation f64" { | ||
| 994 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1280 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 995 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 996 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1281 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 997 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1282 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1283 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 998 | 1284 | ||
| 999 | const S = struct { | 1285 | try testNeg(f32); |
| 1000 | fn doTheTest() !void { | 1286 | try comptime testNeg(f32); |
| 1001 | var a: f64 = 1; | 1287 | try testNeg(f64); |
| 1002 | a = -a; | 1288 | try comptime testNeg(f64); |
| 1003 | try expect(a == -1); | ||
| 1004 | a = -a; | ||
| 1005 | try expect(a == 1); | ||
| 1006 | } | ||
| 1007 | }; | ||
| 1008 | |||
| 1009 | try S.doTheTest(); | ||
| 1010 | try comptime S.doTheTest(); | ||
| 1011 | } | 1289 | } |
| 1012 | 1290 | ||
| 1013 | test "negation f80" { | 1291 | test "neg f80/f128/c_longdouble" { |
| 1014 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1015 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1016 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1292 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1017 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1018 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1019 | |||
| 1020 | const S = struct { | ||
| 1021 | fn doTheTest() !void { | ||
| 1022 | var a: f80 = 1; | ||
| 1023 | a = -a; | ||
| 1024 | try expect(a == -1); | ||
| 1025 | a = -a; | ||
| 1026 | try expect(a == 1); | ||
| 1027 | } | ||
| 1028 | }; | ||
| 1029 | |||
| 1030 | try S.doTheTest(); | ||
| 1031 | try comptime S.doTheTest(); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | test "negation f128" { | ||
| 1035 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1036 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1293 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1037 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1038 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1294 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1039 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1295 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1040 | 1296 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 1041 | const S = struct { | 1297 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 1042 | fn doTheTest() !void { | 1298 | |
| 1043 | var a: f128 = 1; | 1299 | try testNeg(f80); |
| 1044 | a = -a; | 1300 | try comptime testNeg(f80); |
| 1045 | try expect(a == -1); | 1301 | try testNeg(f128); |
| 1046 | a = -a; | 1302 | try comptime testNeg(f128); |
| 1047 | try expect(a == 1); | 1303 | try testNeg(c_longdouble); |
| 1048 | } | 1304 | try comptime testNeg(c_longdouble); |
| 1049 | }; | 1305 | } |
| 1050 | 1306 | ||
| 1051 | try S.doTheTest(); | 1307 | fn testNeg(comptime T: type) !void { |
| 1052 | try comptime S.doTheTest(); | 1308 | var two_point_five: T = 2.5; |
| 1309 | try expect(-two_point_five == -2.5); | ||
| 1310 | var neg_two_point_five: T = -2.5; | ||
| 1311 | try expect(-neg_two_point_five == 2.5); | ||
| 1312 | |||
| 1313 | var twelve: T = 12.0; | ||
| 1314 | try expect(-twelve == -12.0); | ||
| 1315 | var neg_fourteen: T = -14.0; | ||
| 1316 | try expect(-neg_fourteen == 14.0); | ||
| 1317 | |||
| 1318 | // normals | ||
| 1319 | var one: T = 1.0; | ||
| 1320 | try expect(-one == -1.0); | ||
| 1321 | var neg_one: T = -1.0; | ||
| 1322 | try expect(-neg_one == 1.0); | ||
| 1323 | var min: T = math.floatMin(T); | ||
| 1324 | try expect(-min == -math.floatMin(T)); | ||
| 1325 | var neg_min: T = -math.floatMin(T); | ||
| 1326 | try expect(-neg_min == math.floatMin(T)); | ||
| 1327 | var max: T = math.floatMax(T); | ||
| 1328 | try expect(-max == -math.floatMax(T)); | ||
| 1329 | var neg_max: T = -math.floatMax(T); | ||
| 1330 | try expect(-neg_max == math.floatMax(T)); | ||
| 1331 | |||
| 1332 | // subnormals | ||
| 1333 | var zero: T = 0.0; | ||
| 1334 | try expect(-zero == -0.0); | ||
| 1335 | var neg_zero: T = -0.0; | ||
| 1336 | try expect(-neg_zero == 0.0); | ||
| 1337 | var true_min: T = math.floatTrueMin(T); | ||
| 1338 | try expect(-true_min == -math.floatTrueMin(T)); | ||
| 1339 | var neg_true_min: T = -math.floatTrueMin(T); | ||
| 1340 | try expect(-neg_true_min == math.floatTrueMin(T)); | ||
| 1341 | |||
| 1342 | // non-finite numbers | ||
| 1343 | var inf: T = math.inf(T); | ||
| 1344 | try expect(math.isNegativeInf(-inf)); | ||
| 1345 | var neg_inf: T = -math.inf(T); | ||
| 1346 | try expect(math.isPositiveInf(-neg_inf)); | ||
| 1347 | var nan: T = math.nan(T); | ||
| 1348 | try expect(math.isNan(-nan)); | ||
| 1349 | try expect(math.signbit(-nan)); | ||
| 1350 | var neg_nan: T = -math.nan(T); | ||
| 1351 | try expect(math.isNan(-neg_nan)); | ||
| 1352 | try expect(!math.signbit(-neg_nan)); | ||
| 1053 | } | 1353 | } |
| 1054 | 1354 | ||
| 1055 | test "eval @setFloatMode at compile-time" { | 1355 | test "eval @setFloatMode at compile-time" { |
| ... | @@ -1075,11 +1375,11 @@ test "f128 at compile time is lossy" { | ... | @@ -1075,11 +1375,11 @@ test "f128 at compile time is lossy" { |
| 1075 | } | 1375 | } |
| 1076 | 1376 | ||
| 1077 | test "comptime fixed-width float zero divided by zero produces NaN" { | 1377 | test "comptime fixed-width float zero divided by zero produces NaN" { |
| 1078 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1079 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1378 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1080 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1379 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1081 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1380 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1082 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1381 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1382 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 1083 | 1383 | ||
| 1084 | inline for (.{ f16, f32, f64, f80, f128 }) |F| { | 1384 | inline for (.{ f16, f32, f64, f80, f128 }) |F| { |
| 1085 | try expect(math.isNan(@as(F, 0) / @as(F, 0))); | 1385 | try expect(math.isNan(@as(F, 0) / @as(F, 0))); |
| ... | @@ -1104,99 +1404,3 @@ test "comptime fixed-width float non-zero divided by zero produces signed Inf" { | ... | @@ -1104,99 +1404,3 @@ test "comptime fixed-width float non-zero divided by zero produces signed Inf" { |
| 1104 | test "comptime_float zero divided by zero produces zero" { | 1404 | test "comptime_float zero divided by zero produces zero" { |
| 1105 | try expect((0.0 / 0.0) == 0.0); | 1405 | try expect((0.0 / 0.0) == 0.0); |
| 1106 | } | 1406 | } |
| 1107 | |||
| 1108 | test "nan negation f16" { | ||
| 1109 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1110 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1111 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1112 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1113 | |||
| 1114 | const nan_comptime = comptime math.nan(f16); | ||
| 1115 | const neg_nan_comptime = -nan_comptime; | ||
| 1116 | |||
| 1117 | var nan_runtime = math.nan(f16); | ||
| 1118 | const neg_nan_runtime = -nan_runtime; | ||
| 1119 | |||
| 1120 | try expect(!math.signbit(nan_runtime)); | ||
| 1121 | try expect(math.signbit(neg_nan_runtime)); | ||
| 1122 | |||
| 1123 | try expect(!math.signbit(nan_comptime)); | ||
| 1124 | try expect(math.signbit(neg_nan_comptime)); | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | test "nan negation f32" { | ||
| 1128 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1129 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1130 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1131 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1132 | |||
| 1133 | const nan_comptime = comptime math.nan(f32); | ||
| 1134 | const neg_nan_comptime = -nan_comptime; | ||
| 1135 | |||
| 1136 | var nan_runtime = math.nan(f32); | ||
| 1137 | const neg_nan_runtime = -nan_runtime; | ||
| 1138 | |||
| 1139 | try expect(!math.signbit(nan_runtime)); | ||
| 1140 | try expect(math.signbit(neg_nan_runtime)); | ||
| 1141 | |||
| 1142 | try expect(!math.signbit(nan_comptime)); | ||
| 1143 | try expect(math.signbit(neg_nan_comptime)); | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | test "nan negation f64" { | ||
| 1147 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1148 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1149 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1150 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1151 | |||
| 1152 | const nan_comptime = comptime math.nan(f64); | ||
| 1153 | const neg_nan_comptime = -nan_comptime; | ||
| 1154 | |||
| 1155 | var nan_runtime = math.nan(f64); | ||
| 1156 | const neg_nan_runtime = -nan_runtime; | ||
| 1157 | |||
| 1158 | try expect(!math.signbit(nan_runtime)); | ||
| 1159 | try expect(math.signbit(neg_nan_runtime)); | ||
| 1160 | |||
| 1161 | try expect(!math.signbit(nan_comptime)); | ||
| 1162 | try expect(math.signbit(neg_nan_comptime)); | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | test "nan negation f128" { | ||
| 1166 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1168 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1169 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1170 | |||
| 1171 | const nan_comptime = comptime math.nan(f128); | ||
| 1172 | const neg_nan_comptime = -nan_comptime; | ||
| 1173 | |||
| 1174 | var nan_runtime = math.nan(f128); | ||
| 1175 | const neg_nan_runtime = -nan_runtime; | ||
| 1176 | |||
| 1177 | try expect(!math.signbit(nan_runtime)); | ||
| 1178 | try expect(math.signbit(neg_nan_runtime)); | ||
| 1179 | |||
| 1180 | try expect(!math.signbit(nan_comptime)); | ||
| 1181 | try expect(math.signbit(neg_nan_comptime)); | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | test "nan negation f80" { | ||
| 1185 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1186 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1187 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1188 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1189 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1190 | |||
| 1191 | const nan_comptime = comptime math.nan(f80); | ||
| 1192 | const neg_nan_comptime = -nan_comptime; | ||
| 1193 | |||
| 1194 | var nan_runtime = math.nan(f80); | ||
| 1195 | const neg_nan_runtime = -nan_runtime; | ||
| 1196 | |||
| 1197 | try expect(!math.signbit(nan_runtime)); | ||
| 1198 | try expect(math.signbit(neg_nan_runtime)); | ||
| 1199 | |||
| 1200 | try expect(!math.signbit(nan_comptime)); | ||
| 1201 | try expect(math.signbit(neg_nan_comptime)); | ||
| 1202 | } |
test/behavior/math.zig+16-11| ... | @@ -410,12 +410,11 @@ fn testBinaryNot128(comptime Type: type, x: Type) !void { | ... | @@ -410,12 +410,11 @@ fn testBinaryNot128(comptime Type: type, x: Type) !void { |
| 410 | 410 | ||
| 411 | test "division" { | 411 | test "division" { |
| 412 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 412 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 413 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 414 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 415 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 413 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 416 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 414 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 417 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 415 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 418 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 416 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 417 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 419 | 418 | ||
| 420 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) { | 419 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) { |
| 421 | // https://github.com/ziglang/zig/issues/16846 | 420 | // https://github.com/ziglang/zig/issues/16846 |
| ... | @@ -1437,19 +1436,28 @@ fn fmodOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void { | ... | @@ -1437,19 +1436,28 @@ fn fmodOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void { |
| 1437 | try expect(@abs(@mod(@as(T, a), @as(T, b)) - @as(T, c)) < epsilon); | 1436 | try expect(@abs(@mod(@as(T, a), @as(T, b)) - @as(T, c)) < epsilon); |
| 1438 | } | 1437 | } |
| 1439 | 1438 | ||
| 1440 | test "@round" { | 1439 | test "@round f16" { |
| 1441 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1440 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1442 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1441 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1443 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1444 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1442 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1445 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1443 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1444 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 1445 | |||
| 1446 | try testRound(f16, 12.0); | ||
| 1447 | try comptime testRound(f16, 12.0); | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | test "@round f32/f64" { | ||
| 1451 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1452 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1453 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 1454 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 1455 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 1446 | 1456 | ||
| 1447 | try testRound(f64, 12.0); | 1457 | try testRound(f64, 12.0); |
| 1448 | try comptime testRound(f64, 12.0); | 1458 | try comptime testRound(f64, 12.0); |
| 1449 | try testRound(f32, 12.0); | 1459 | try testRound(f32, 12.0); |
| 1450 | try comptime testRound(f32, 12.0); | 1460 | try comptime testRound(f32, 12.0); |
| 1451 | try testRound(f16, 12.0); | ||
| 1452 | try comptime testRound(f16, 12.0); | ||
| 1453 | 1461 | ||
| 1454 | const x = 14.0; | 1462 | const x = 14.0; |
| 1455 | const y = x + 0.4; | 1463 | const y = x + 0.4; |
| ... | @@ -1464,6 +1472,7 @@ test "@round f80" { | ... | @@ -1464,6 +1472,7 @@ test "@round f80" { |
| 1464 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1472 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1465 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1473 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1466 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 1474 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| 1475 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 1467 | 1476 | ||
| 1468 | try testRound(f80, 12.0); | 1477 | try testRound(f80, 12.0); |
| 1469 | try comptime testRound(f80, 12.0); | 1478 | try comptime testRound(f80, 12.0); |
| ... | @@ -1476,6 +1485,7 @@ test "@round f128" { | ... | @@ -1476,6 +1485,7 @@ test "@round f128" { |
| 1476 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1485 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1477 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1486 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1478 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 1487 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| 1488 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 1479 | 1489 | ||
| 1480 | try testRound(f128, 12.0); | 1490 | try testRound(f128, 12.0); |
| 1481 | try comptime testRound(f128, 12.0); | 1491 | try comptime testRound(f128, 12.0); |
| ... | @@ -1608,11 +1618,6 @@ test "signed zeros are represented properly" { | ... | @@ -1608,11 +1618,6 @@ test "signed zeros are represented properly" { |
| 1608 | try comptime S.doTheTest(); | 1618 | try comptime S.doTheTest(); |
| 1609 | } | 1619 | } |
| 1610 | 1620 | ||
| 1611 | test "comptime sin and ln" { | ||
| 1612 | const v = comptime (@sin(@as(f32, 1)) + @log(@as(f32, 5))); | ||
| 1613 | try expect(v == @sin(@as(f32, 1)) + @log(@as(f32, 5))); | ||
| 1614 | } | ||
| 1615 | |||
| 1616 | test "absFloat" { | 1621 | test "absFloat" { |
| 1617 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1622 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1618 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1623 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/maximum_minimum.zig+7-8| ... | @@ -10,6 +10,7 @@ test "@max" { | ... | @@ -10,6 +10,7 @@ test "@max" { |
| 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 13 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 13 | 14 | ||
| 14 | const S = struct { | 15 | const S = struct { |
| 15 | fn doTheTest() !void { | 16 | fn doTheTest() !void { |
| ... | @@ -25,12 +26,11 @@ test "@max" { | ... | @@ -25,12 +26,11 @@ test "@max" { |
| 25 | 26 | ||
| 26 | test "@max on vectors" { | 27 | test "@max on vectors" { |
| 27 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 28 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 28 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 29 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 30 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 29 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 31 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 30 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 33 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 32 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 33 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 34 | 34 | ||
| 35 | const S = struct { | 35 | const S = struct { |
| 36 | fn doTheTest() !void { | 36 | fn doTheTest() !void { |
| ... | @@ -74,12 +74,11 @@ test "@min" { | ... | @@ -74,12 +74,11 @@ test "@min" { |
| 74 | 74 | ||
| 75 | test "@min for vectors" { | 75 | test "@min for vectors" { |
| 76 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 76 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 77 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 78 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 79 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 80 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 78 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 81 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 82 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 80 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 81 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 83 | 82 | ||
| 84 | const S = struct { | 83 | const S = struct { |
| 85 | fn doTheTest() !void { | 84 | fn doTheTest() !void { |
| ... | @@ -104,12 +103,12 @@ test "@min for vectors" { | ... | @@ -104,12 +103,12 @@ test "@min for vectors" { |
| 104 | } | 103 | } |
| 105 | 104 | ||
| 106 | test "@min/max for floats" { | 105 | test "@min/max for floats" { |
| 107 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 108 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 106 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 109 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 107 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 110 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 108 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 111 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 109 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 112 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; | 110 | if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; |
| 111 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 113 | 112 | ||
| 114 | const S = struct { | 113 | const S = struct { |
| 115 | fn doTheTest(comptime T: type) !void { | 114 | fn doTheTest(comptime T: type) !void { |
| ... | @@ -179,11 +178,11 @@ test "@min/@max notices bounds" { | ... | @@ -179,11 +178,11 @@ test "@min/@max notices bounds" { |
| 179 | 178 | ||
| 180 | test "@min/@max notices vector bounds" { | 179 | test "@min/@max notices vector bounds" { |
| 181 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 180 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 182 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 183 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 184 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 182 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 185 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 183 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 186 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 184 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 185 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 187 | 186 | ||
| 188 | var x: @Vector(2, u16) = .{ 140, 40 }; | 187 | var x: @Vector(2, u16) = .{ 140, 40 }; |
| 189 | const y: @Vector(2, u64) = .{ 5, 100 }; | 188 | const y: @Vector(2, u64) = .{ 5, 100 }; |
| ... | @@ -232,11 +231,11 @@ test "@min/@max notices bounds from types" { | ... | @@ -232,11 +231,11 @@ test "@min/@max notices bounds from types" { |
| 232 | 231 | ||
| 233 | test "@min/@max notices bounds from vector types" { | 232 | test "@min/@max notices bounds from vector types" { |
| 234 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 233 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 235 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 236 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 234 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 237 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 235 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 238 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 236 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 239 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 237 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 238 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 240 | 239 | ||
| 241 | var x: @Vector(2, u16) = .{ 30, 67 }; | 240 | var x: @Vector(2, u16) = .{ 30, 67 }; |
| 242 | var y: @Vector(2, u32) = .{ 20, 500 }; | 241 | var y: @Vector(2, u32) = .{ 20, 500 }; |
| ... | @@ -272,11 +271,11 @@ test "@min/@max notices bounds from types when comptime-known value is undef" { | ... | @@ -272,11 +271,11 @@ test "@min/@max notices bounds from types when comptime-known value is undef" { |
| 272 | 271 | ||
| 273 | test "@min/@max notices bounds from vector types when element of comptime-known vector is undef" { | 272 | test "@min/@max notices bounds from vector types when element of comptime-known vector is undef" { |
| 274 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 273 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 275 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 276 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 274 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 277 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 275 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 278 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 276 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 279 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 277 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 278 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 280 | 279 | ||
| 281 | var x: @Vector(2, u32) = .{ 1_000_000, 12345 }; | 280 | var x: @Vector(2, u32) = .{ 1_000_000, 12345 }; |
| 282 | const y: @Vector(2, u16) = .{ 10, undefined }; | 281 | const y: @Vector(2, u16) = .{ 10, undefined }; |
test/behavior/struct.zig-2| ... | @@ -1651,7 +1651,6 @@ test "instantiate struct with comptime field" { | ... | @@ -1651,7 +1651,6 @@ test "instantiate struct with comptime field" { |
| 1651 | test "struct field pointer has correct alignment" { | 1651 | test "struct field pointer has correct alignment" { |
| 1652 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1652 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1653 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1653 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1654 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1655 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1654 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1656 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1655 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1657 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1656 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1684,7 +1683,6 @@ test "struct field pointer has correct alignment" { | ... | @@ -1684,7 +1683,6 @@ test "struct field pointer has correct alignment" { |
| 1684 | test "extern struct field pointer has correct alignment" { | 1683 | test "extern struct field pointer has correct alignment" { |
| 1685 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1684 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1686 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1685 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1687 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1688 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1686 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1689 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1687 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1690 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1688 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/union.zig-3| ... | @@ -1534,7 +1534,6 @@ test "coerce enum literal to union in result loc" { | ... | @@ -1534,7 +1534,6 @@ test "coerce enum literal to union in result loc" { |
| 1534 | test "defined-layout union field pointer has correct alignment" { | 1534 | test "defined-layout union field pointer has correct alignment" { |
| 1535 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1535 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1536 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1536 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1537 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1538 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1537 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1539 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1538 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1540 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1539 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1572,7 +1571,6 @@ test "defined-layout union field pointer has correct alignment" { | ... | @@ -1572,7 +1571,6 @@ test "defined-layout union field pointer has correct alignment" { |
| 1572 | test "undefined-layout union field pointer has correct alignment" { | 1571 | test "undefined-layout union field pointer has correct alignment" { |
| 1573 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1572 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1574 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1573 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1575 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1576 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1574 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1577 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1575 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1578 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1576 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1610,7 +1608,6 @@ test "undefined-layout union field pointer has correct alignment" { | ... | @@ -1610,7 +1608,6 @@ test "undefined-layout union field pointer has correct alignment" { |
| 1610 | test "packed union field pointer has correct alignment" { | 1608 | test "packed union field pointer has correct alignment" { |
| 1611 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 1609 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1612 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1610 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1613 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1614 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1611 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1615 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1612 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1616 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1613 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/vector.zig+4-10| ... | @@ -8,7 +8,6 @@ const expectEqual = std.testing.expectEqual; | ... | @@ -8,7 +8,6 @@ const expectEqual = std.testing.expectEqual; |
| 8 | 8 | ||
| 9 | test "implicit cast vector to array - bool" { | 9 | test "implicit cast vector to array - bool" { |
| 10 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 12 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 13 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 12 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 14 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 13 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -27,12 +26,12 @@ test "implicit cast vector to array - bool" { | ... | @@ -27,12 +26,12 @@ test "implicit cast vector to array - bool" { |
| 27 | 26 | ||
| 28 | test "vector wrap operators" { | 27 | test "vector wrap operators" { |
| 29 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 28 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 30 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 31 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 32 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 29 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 33 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 30 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 34 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 35 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 32 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 33 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 34 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 36 | 35 | ||
| 37 | const S = struct { | 36 | const S = struct { |
| 38 | fn doTheTest() !void { | 37 | fn doTheTest() !void { |
| ... | @@ -214,13 +213,12 @@ test "array vector coercion - odd sizes" { | ... | @@ -214,13 +213,12 @@ test "array vector coercion - odd sizes" { |
| 214 | } | 213 | } |
| 215 | 214 | ||
| 216 | test "array to vector with element type coercion" { | 215 | test "array to vector with element type coercion" { |
| 217 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 218 | if (builtin.zig_backend == .stage2_x86_64 and | ||
| 219 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; // TODO | ||
| 220 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 216 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 221 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 217 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 222 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 218 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 223 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 219 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 220 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 221 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 224 | 222 | ||
| 225 | const S = struct { | 223 | const S = struct { |
| 226 | fn doTheTest() !void { | 224 | fn doTheTest() !void { |
| ... | @@ -236,7 +234,6 @@ test "array to vector with element type coercion" { | ... | @@ -236,7 +234,6 @@ test "array to vector with element type coercion" { |
| 236 | 234 | ||
| 237 | test "peer type resolution with coercible element types" { | 235 | test "peer type resolution with coercible element types" { |
| 238 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 236 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 239 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 240 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 237 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 241 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 238 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 242 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 239 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1440,7 +1437,6 @@ test "vector pointer is indexable" { | ... | @@ -1440,7 +1437,6 @@ test "vector pointer is indexable" { |
| 1440 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1437 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1441 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1438 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1442 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1439 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1443 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1444 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1440 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1445 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1441 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 1446 | 1442 | ||
| ... | @@ -1466,7 +1462,6 @@ test "boolean vector with 2 or more booleans" { | ... | @@ -1466,7 +1462,6 @@ test "boolean vector with 2 or more booleans" { |
| 1466 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1462 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1467 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1463 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1468 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1464 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1469 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1470 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1465 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1471 | 1466 | ||
| 1472 | // TODO: try removing this after <https://github.com/ziglang/zig/issues/13782>: | 1467 | // TODO: try removing this after <https://github.com/ziglang/zig/issues/13782>: |
| ... | @@ -1483,7 +1478,6 @@ test "bitcast to vector with different child type" { | ... | @@ -1483,7 +1478,6 @@ test "bitcast to vector with different child type" { |
| 1483 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1478 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1484 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1479 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1485 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1480 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1486 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1487 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1481 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1488 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | 1482 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO |
| 1489 | 1483 |