authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-09-23 06:21:03-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-01 15:09:52-04:00
log3bd1b9e15f04128fa3a2c0c3c3969852b7cde9f2
tree8845f2091d6aa7755de86427718472e5972337ae
parentaf40bce08adf232c9f6b9016810a24f7d0260399

x86_64: implement and test unary float builtins


7 files changed, 596 insertions(+), 330 deletions(-)

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 specially1874 // 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
54075407
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`.
5409pub const GetFuncTypeKey = struct {5409pub 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};
54245424
5425pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index {5425pub 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 });
57675762
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);
73747374
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(
2114421144
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+182-138
...@@ -1807,7 +1807,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1807,7 +1807,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1807 .log2,1807 .log2,
1808 .log10,1808 .log10,
1809 .round,1809 .round,
1810 => try self.airUnaryMath(inst),1810 => |tag| try self.airUnaryMath(inst, tag),
18111811
1812 .floor => try self.airRound(inst, 0b1_0_01),1812 .floor => try self.airRound(inst, 0b1_0_01),
1813 .ceil => try self.airRound(inst, 0b1_0_10),1813 .ceil => try self.airRound(inst, 0b1_0_10),
...@@ -5280,13 +5280,35 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -5280,13 +5280,35 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5280 return self.finishAir(inst, result, .{ un_op, .none, .none });5280 return self.finishAir(inst, result, .{ un_op, .none, .none });
5281}5281}
52825282
5283fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {5283fn airUnaryMath(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
5284 const un_op = self.air.instructions.items(.data)[inst].un_op;5284 const un_op = self.air.instructions.items(.data)[inst].un_op;
5285 _ = un_op;5285 const ty = self.typeOf(un_op).toIntern();
5286 return self.fail("TODO implement airUnaryMath for {}", .{5286 const result = try self.genCall(.{ .lib = .{
5287 self.air.instructions.items(.tag)[inst],5287 .return_type = ty,
5288 });5288 .param_types = &.{ty},
5289 //return self.finishAir(inst, result, .{ un_op, .none, .none });5289 .callee = switch (tag) {
5290 inline .sin,
5291 .cos,
5292 .tan,
5293 .exp,
5294 .exp2,
5295 .log,
5296 .log2,
5297 .log10,
5298 .round,
5299 => |comptime_tag| switch (ty) {
5300 .f16_type => "__" ++ @tagName(comptime_tag) ++ "h",
5301 .f32_type => @tagName(comptime_tag) ++ "f",
5302 .f64_type => @tagName(comptime_tag),
5303 .f80_type => "__" ++ @tagName(comptime_tag) ++ "x",
5304 .f128_type => @tagName(comptime_tag) ++ "q",
5305 .c_longdouble_type => @tagName(comptime_tag) ++ "l",
5306 else => unreachable,
5307 },
5308 else => unreachable,
5309 },
5310 } }, &.{un_op});
5311 return self.finishAir(inst, result, .{ un_op, .none, .none });
5290}5312}
52915313
5292fn reuseOperand(5314fn reuseOperand(
...@@ -7290,7 +7312,7 @@ fn genBinOp(...@@ -7290,7 +7312,7 @@ fn genBinOp(
72907312
7291 switch (air_tag) {7313 switch (air_tag) {
7292 .add, .add_wrap, .sub, .sub_wrap, .mul, .mul_wrap, .div_float, .div_exact => {},7314 .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(7315 .div_trunc, .div_floor => try self.genRound(
7294 lhs_ty,7316 lhs_ty,
7295 dst_reg,7317 dst_reg,
7296 .{ .register = dst_reg },7318 .{ .register = dst_reg },
...@@ -7299,9 +7321,7 @@ fn genBinOp(...@@ -7299,9 +7321,7 @@ fn genBinOp(
7299 .div_floor => 0b1_0_01,7321 .div_floor => 0b1_0_01,
7300 else => unreachable,7322 else => unreachable,
7301 },7323 },
7302 ) else return self.fail("TODO implement genBinOp for {s} {} without sse4_1 feature", .{7324 ),
7303 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7304 }),
7305 .bit_and, .bit_or, .xor => {},7325 .bit_and, .bit_or, .xor => {},
7306 .max, .min => if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx)) {7326 .max, .min => if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx)) {
7307 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);7327 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
...@@ -8124,31 +8144,59 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {...@@ -8124,31 +8144,59 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {
8124}8144}
81258145
8126fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {8146fn 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", .{});8147 if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{});
8148
8129 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8149 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);8150 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]);8151 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
8133 const ty = self.typeOf(callee);
81348152
8135 const fn_ty = switch (ty.zigTypeTag(mod)) {8153 const ret = try self.genCall(.{ .air = pl_op.operand }, args);
8136 .Fn => ty,8154
8137 .Pointer => ty.childType(mod),8155 var bt = self.liveness.iterateBigTomb(inst);
8138 else => unreachable,8156 self.feed(&bt, pl_op.operand);
8139 };8157 for (args) |arg| self.feed(&bt, arg);
81408158
8159 const result = if (self.liveness.isUnused(inst)) .unreach else ret;
8160 return self.finishAirResult(inst, result);
8161}
8162
8163fn genCall(self: *Self, info: union(enum) {
8164 air: Air.Inst.Ref,
8165 lib: struct {
8166 return_type: InternPool.Index,
8167 param_types: []const InternPool.Index,
8168 lib: ?[]const u8 = null,
8169 callee: []const u8,
8170 },
8171}, args: []const Air.Inst.Ref) !MCValue {
8172 const mod = self.bin_file.options.module.?;
8173
8174 const fn_ty = switch (info) {
8175 .air => |callee| fn_info: {
8176 const callee_ty = self.typeOf(callee);
8177 break :fn_info switch (callee_ty.zigTypeTag(mod)) {
8178 .Fn => callee_ty,
8179 .Pointer => callee_ty.childType(mod),
8180 else => unreachable,
8181 };
8182 },
8183 .lib => |lib| try mod.funcType(.{
8184 .param_types = lib.param_types,
8185 .return_type = lib.return_type,
8186 .cc = .C,
8187 }),
8188 };
8141 const fn_info = mod.typeToFunc(fn_ty).?;8189 const fn_info = mod.typeToFunc(fn_ty).?;
81428190
8143 var info = try self.resolveCallingConventionValues(fn_info, args[fn_info.param_types.len..], .call_frame);8191 var call_info =
8144 defer info.deinit(self);8192 try self.resolveCallingConventionValues(fn_info, args[fn_info.param_types.len..], .call_frame);
8193 defer call_info.deinit(self);
81458194
8146 // We need a properly aligned and sized call frame to be able to call this function.8195 // We need a properly aligned and sized call frame to be able to call this function.
8147 {8196 {
8148 const needed_call_frame =8197 const needed_call_frame = FrameAlloc.init(.{
8149 FrameAlloc.init(.{8198 .size = call_info.stack_byte_count,
8150 .size = info.stack_byte_count,8199 .alignment = call_info.stack_align,
8151 .alignment = info.stack_align,
8152 });8200 });
8153 const frame_allocs_slice = self.frame_allocs.slice();8201 const frame_allocs_slice = self.frame_allocs.slice();
8154 const stack_frame_size =8202 const stack_frame_size =
...@@ -8164,24 +8212,20 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8164,24 +8212,20 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81648212
8165 // set stack arguments first because this can clobber registers8213 // set stack arguments first because this can clobber registers
8166 // also clobber spill arguments as we go8214 // also clobber spill arguments as we go
8167 switch (info.return_value.long) {8215 switch (call_info.return_value.long) {
8168 .none, .unreach => {},8216 .none, .unreach => {},
8169 .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}),8217 .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}),
8170 else => unreachable,8218 else => unreachable,
8171 }8219 }
8172 for (args, info.args) |arg, mc_arg| {8220 for (call_info.args, args) |dst_arg, src_arg| switch (dst_arg) {
8173 const arg_ty = self.typeOf(arg);8221 .none => {},
8174 const arg_mcv = try self.resolveInst(arg);8222 .register => |reg| try self.spillRegisters(&.{reg}),
8175 switch (mc_arg) {8223 .load_frame => try self.genCopy(self.typeOf(src_arg), dst_arg, try self.resolveInst(src_arg)),
8176 .none => {},8224 else => unreachable,
8177 .register => |reg| try self.spillRegisters(&.{reg}),8225 };
8178 .load_frame => try self.genCopy(arg_ty, mc_arg, arg_mcv),
8179 else => unreachable,
8180 }
8181 }
81828226
8183 // now we are free to set register arguments8227 // now we are free to set register arguments
8184 const ret_lock = switch (info.return_value.long) {8228 const ret_lock = switch (call_info.return_value.long) {
8185 .none, .unreach => null,8229 .none, .unreach => null,
8186 .indirect => |reg_off| lock: {8230 .indirect => |reg_off| lock: {
8187 const ret_ty = fn_info.return_type.toType();8231 const ret_ty = fn_info.return_type.toType();
...@@ -8189,125 +8233,80 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8189,125 +8233,80 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8189 try self.genSetReg(reg_off.reg, Type.usize, .{8233 try self.genSetReg(reg_off.reg, Type.usize, .{
8190 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },8234 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
8191 });8235 });
8192 info.return_value.short = .{ .load_frame = .{ .index = frame_index } };8236 call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } };
8193 break :lock self.register_manager.lockRegAssumeUnused(reg_off.reg);8237 break :lock self.register_manager.lockRegAssumeUnused(reg_off.reg);
8194 },8238 },
8195 else => unreachable,8239 else => unreachable,
8196 };8240 };
8197 defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);8241 defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);
81988242
8199 for (args, info.args) |arg, mc_arg| {8243 for (call_info.args, args) |dst_arg, src_arg| {
8200 const arg_ty = self.typeOf(arg);8244 switch (dst_arg) {
8201 const arg_mcv = try self.resolveInst(arg);
8202 switch (mc_arg) {
8203 .none, .load_frame => {},8245 .none, .load_frame => {},
8204 .register => try self.genCopy(arg_ty, mc_arg, arg_mcv),8246 .register => try self.genCopy(self.typeOf(src_arg), dst_arg, try self.resolveInst(src_arg)),
8205 else => unreachable,8247 else => unreachable,
8206 }8248 }
8207 }8249 }
82088250
8209 // Due to incremental compilation, how function calls are generated depends8251 // Due to incremental compilation, how function calls are generated depends
8210 // on linking.8252 // on linking.
8211 if (try self.air.value(callee, mod)) |func_value| {8253 switch (info) {
8212 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);8254 .air => |callee| if (try self.air.value(callee, mod)) |func_value| {
8213 if (switch (func_key) {8255 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);
8214 .func => |func| func.owner_decl,8256 if (switch (func_key) {
8215 .ptr => |ptr| switch (ptr.addr) {8257 .func => |func| func.owner_decl,
8216 .decl => |decl| decl,8258 .ptr => |ptr| switch (ptr.addr) {
8259 .decl => |decl| decl,
8260 else => null,
8261 },
8217 else => null,8262 else => null,
8218 },8263 }) |owner_decl| {
8219 else => null,8264 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8220 }) |owner_decl| {8265 const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl);
8221 if (self.bin_file.cast(link.File.Elf)) |elf_file| {8266 const sym = elf_file.symbol(sym_index);
8222 const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl);8267 sym.flags.needs_got = true;
8223 const sym = elf_file.symbol(sym_index);8268 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);
8224 sym.flags.needs_got = true;8269 _ = try self.addInst(.{
8225 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);8270 .tag = .call,
8226 _ = try self.addInst(.{8271 .ops = .direct_got_reloc,
8227 .tag = .call,8272 .data = .{ .reloc = .{
8228 .ops = .direct_got_reloc,8273 .atom_index = try self.owner.getSymbolIndex(self),
8229 .data = .{ .reloc = .{8274 .sym_index = sym.esym_index,
8230 .atom_index = try self.owner.getSymbolIndex(self),8275 } },
8231 .sym_index = sym.esym_index,8276 });
8232 } },8277 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8233 });8278 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);
8234 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {8279 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
8235 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);8280 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8236 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;8281 try self.asmRegister(.{ ._, .call }, .rax);
8237 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });8282 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8238 try self.asmRegister(.{ ._, .call }, .rax);8283 const atom = try macho_file.getOrCreateAtomForDecl(owner_decl);
8239 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {8284 const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
8240 const atom = try macho_file.getOrCreateAtomForDecl(owner_decl);8285 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8241 const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;8286 try self.asmRegister(.{ ._, .call }, .rax);
8242 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });8287 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
8243 try self.asmRegister(.{ ._, .call }, .rax);8288 const atom_index = try p9.seeDecl(owner_decl);
8244 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {8289 const atom = p9.getAtom(atom_index);
8245 const atom_index = try p9.seeDecl(owner_decl);8290 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
8246 const atom = p9.getAtom(atom_index);8291 .base = .{ .reg = .ds },
8247 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{8292 .disp = @intCast(atom.getOffsetTableAddress(p9)),
8248 .base = .{ .reg = .ds },8293 }));
8249 .disp = @intCast(atom.getOffsetTableAddress(p9)),8294 } else unreachable;
8250 }));8295 } else if (func_value.getExternFunc(mod)) |extern_func| {
8251 } else unreachable;8296 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
8252 } else if (func_value.getExternFunc(mod)) |extern_func| {8297 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);8298 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 {8299 } else {
8293 return self.fail("TODO implement calling extern functions", .{});8300 return self.fail("TODO implement calling bitcasted functions", .{});
8294 }8301 }
8295 } else {8302 } else {
8296 return self.fail("TODO implement calling bitcasted functions", .{});8303 assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer);
8297 }8304 try self.genSetReg(.rax, Type.usize, try self.resolveInst(callee));
8298 } else {8305 try self.asmRegister(.{ ._, .call }, .rax);
8299 assert(ty.zigTypeTag(mod) == .Pointer);8306 },
8300 const mcv = try self.resolveInst(callee);8307 .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 }8308 }
83048309 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}8310}
83128311
8313fn airRet(self: *Self, inst: Air.Inst.Index) !void {8312fn airRet(self: *Self, inst: Air.Inst.Index) !void {
...@@ -10281,6 +10280,51 @@ fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue)...@@ -10281,6 +10280,51 @@ fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue)
10281 try self.asmOpOnly(.{ .@"rep _sb", .sto });10280 try self.asmOpOnly(.{ .@"rep _sb", .sto });
10282}10281}
1028310282
10283fn genExternSymbolRef(
10284 self: *Self,
10285 comptime tag: Mir.Inst.Tag,
10286 lib: ?[]const u8,
10287 callee: []const u8,
10288) InnerError!void {
10289 const atom_index = try self.owner.getSymbolIndex(self);
10290 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
10291 _ = try self.addInst(.{
10292 .tag = tag,
10293 .ops = .extern_fn_reloc,
10294 .data = .{ .reloc = .{
10295 .atom_index = atom_index,
10296 .sym_index = try elf_file.getGlobalSymbol(callee, lib),
10297 } },
10298 });
10299 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
10300 _ = try self.addInst(.{
10301 .tag = .mov,
10302 .ops = .import_reloc,
10303 .data = .{ .rx = .{
10304 .r1 = .rax,
10305 .payload = try self.addExtra(Mir.Reloc{
10306 .atom_index = atom_index,
10307 .sym_index = try coff_file.getGlobalSymbol(callee, lib),
10308 }),
10309 } },
10310 });
10311 switch (tag) {
10312 .mov => {},
10313 .call => try self.asmRegister(.{ ._, .call }, .rax),
10314 else => unreachable,
10315 }
10316 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
10317 _ = try self.addInst(.{
10318 .tag = .call,
10319 .ops = .extern_fn_reloc,
10320 .data = .{ .reloc = .{
10321 .atom_index = atom_index,
10322 .sym_index = try macho_file.getGlobalSymbol(callee, lib),
10323 } },
10324 });
10325 } else return self.fail("TODO implement calling extern functions", .{});
10326}
10327
10284fn genLazySymbolRef(10328fn genLazySymbolRef(
10285 self: *Self,10329 self: *Self,
10286 comptime tag: Mir.Inst.Tag,10330 comptime tag: Mir.Inst.Tag,
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/floatop.zig+382-149
...@@ -2,8 +2,6 @@ const std = @import("std");...@@ -2,8 +2,6 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const expect = std.testing.expect;3const expect = std.testing.expect;
4const math = std.math;4const math = std.math;
5const pi = std.math.pi;
6const e = std.math.e;
7const has_f80_rt = switch (builtin.cpu.arch) {5const has_f80_rt = switch (builtin.cpu.arch) {
8 .x86_64, .x86 => true,6 .x86_64, .x86 => true,
9 else => false,7 else => false,
...@@ -11,7 +9,7 @@ const has_f80_rt = switch (builtin.cpu.arch) {...@@ -11,7 +9,7 @@ const has_f80_rt = switch (builtin.cpu.arch) {
11const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and9const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and
12 !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c);10 !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c);
1311
14const epsilon_16 = 0.001;12const epsilon_16 = 0.002;
15const epsilon = 0.000001;13const epsilon = 0.000001;
1614
17fn epsForType(comptime T: type) T {15fn epsForType(comptime T: type) T {
...@@ -29,10 +27,10 @@ test "floating point comparisons" {...@@ -29,10 +27,10 @@ test "floating point comparisons" {
29}27}
3028
31fn testFloatComparisons() !void {29fn testFloatComparisons() !void {
32 inline for ([_]type{ f16, f32, f64, f128 }) |ty| {30 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
33 // No decimal part31 // No decimal part
34 {32 {
35 const x: ty = 1.0;33 const x: T = 1.0;
36 try expect(x == 1);34 try expect(x == 1);
37 try expect(x != 0);35 try expect(x != 0);
38 try expect(x > 0);36 try expect(x > 0);
...@@ -42,7 +40,7 @@ fn testFloatComparisons() !void {...@@ -42,7 +40,7 @@ fn testFloatComparisons() !void {
42 }40 }
43 // Non-zero decimal part41 // Non-zero decimal part
44 {42 {
45 const x: ty = 1.5;43 const x: T = 1.5;
46 try expect(x != 1);44 try expect(x != 1);
47 try expect(x != 2);45 try expect(x != 2);
48 try expect(x > 1);46 try expect(x > 1);
...@@ -54,11 +52,11 @@ fn testFloatComparisons() !void {...@@ -54,11 +52,11 @@ fn testFloatComparisons() !void {
54}52}
5553
56test "different sized float comparisons" {54test "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; // TODO55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO57 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;58 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
59 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
6260
63 try testDifferentSizedFloatComparisons();61 try testDifferentSizedFloatComparisons();
64 try comptime testDifferentSizedFloatComparisons();62 try comptime testDifferentSizedFloatComparisons();
...@@ -73,9 +71,9 @@ fn testDifferentSizedFloatComparisons() !void {...@@ -73,9 +71,9 @@ fn testDifferentSizedFloatComparisons() !void {
73test "f80 comparisons" {71test "f80 comparisons" {
74 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO72 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
75 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO73 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;74 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;75 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7977
80 try expect(compareF80(0.0, .eq, -0.0));78 try expect(compareF80(0.0, .eq, -0.0));
81 try expect(compareF80(0.0, .lte, -0.0));79 try expect(compareF80(0.0, .lte, -0.0));
...@@ -125,8 +123,8 @@ test "@sqrt" {...@@ -125,8 +123,8 @@ test "@sqrt" {
125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;124 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
127125
128 try comptime testSqrt();
129 try testSqrt();126 try testSqrt();
127 try comptime testSqrt();
130}128}
131129
132fn testSqrt() !void {130fn testSqrt() !void {
...@@ -163,8 +161,8 @@ test "@sqrt with vectors" {...@@ -163,8 +161,8 @@ test "@sqrt with vectors" {
163 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO161 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
164 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;162 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
165163
166 try comptime testSqrtWithVectors();
167 try testSqrtWithVectors();164 try testSqrtWithVectors();
165 try comptime testSqrtWithVectors();
168}166}
169167
170fn testSqrtWithVectors() !void {168fn testSqrtWithVectors() !void {
...@@ -177,11 +175,11 @@ fn testSqrtWithVectors() !void {...@@ -177,11 +175,11 @@ fn testSqrtWithVectors() !void {
177}175}
178176
179test "more @sqrt f16 tests" {177test "more @sqrt f16 tests" {
180 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO178 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO180 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;181 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
182 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
185183
186 // TODO these are not all passing at comptime184 // TODO these are not all passing at comptime
187 try expect(@sqrt(@as(f16, 0.0)) == 0.0);185 try expect(@sqrt(@as(f16, 0.0)) == 0.0);
...@@ -205,8 +203,8 @@ test "more @sqrt f16 tests" {...@@ -205,8 +203,8 @@ test "more @sqrt f16 tests" {
205test "another, possibly redundant @sqrt test" {203test "another, possibly redundant @sqrt test" {
206 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
207 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO205 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
208 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
209 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;206 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
207 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
210208
211 try testSqrtLegacy(f64, 12.0);209 try testSqrtLegacy(f64, 12.0);
212 try comptime testSqrtLegacy(f64, 12.0);210 try comptime testSqrtLegacy(f64, 12.0);
...@@ -228,36 +226,61 @@ fn testSqrtLegacy(comptime T: type, x: T) !void {...@@ -228,36 +226,61 @@ fn testSqrtLegacy(comptime T: type, x: T) !void {
228 try expect(@sqrt(x * x) == x);226 try expect(@sqrt(x * x) == x);
229}227}
230228
231test "@sin" {229test "@sin f16" {
232 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO230 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
231 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
233 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
234 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
235 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
236
237 try testSin(&.{f16});
238 try comptime testSin(&.{f16});
239}
240
241test "@sin f32/f64" {
233 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO242 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
234 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO243 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
235 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
236 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;245 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
246 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
237247
238 try comptime testSin();248 try testSin(&.{ f32, f64 });
239 try testSin();249 try comptime testSin(&.{ f32, f64 });
240}250}
241251
242fn testSin() !void {252test "@sin f80/f128/c_longdouble" {
243 inline for ([_]type{ f16, f32, f64 }) |ty| {253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
244 const eps = epsForType(ty);254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
245 try expect(@sin(@as(ty, 0)) == 0);255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
246 try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi)), 0, eps));256 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
247 try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 2.0)), 1, eps));257 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
248 try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps));258
259 try testSin(&.{ f80, f128, c_longdouble });
260 try comptime testSin(&.{ f80, f128, c_longdouble });
261}
262
263fn testSin(comptime Ts: []const type) !void {
264 inline for (Ts) |T| {
265 const eps = epsForType(T);
266 var zero: T = 0;
267 try expect(@sin(zero) == 0);
268 var pi: T = std.math.pi;
269 try expect(math.approxEqAbs(T, @sin(pi), 0, eps));
270 try expect(math.approxEqAbs(T, @sin(pi / 2.0), 1, eps));
271 try expect(math.approxEqAbs(T, @sin(pi / 4.0), 0.7071067811865475, eps));
249 }272 }
250}273}
251274
252test "@sin with vectors" {275test "@sin with vectors" {
253 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO276 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; // TODO277 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO278 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
257 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;279 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
280 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
258281
259 try comptime testSinWithVectors();
260 try testSinWithVectors();282 try testSinWithVectors();
283 try comptime testSinWithVectors();
261}284}
262285
263fn testSinWithVectors() !void {286fn testSinWithVectors() !void {
...@@ -269,36 +292,61 @@ fn testSinWithVectors() !void {...@@ -269,36 +292,61 @@ fn testSinWithVectors() !void {
269 try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon));292 try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon));
270}293}
271294
272test "@cos" {295test "@cos f16" {
273 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO296 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
297 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
298 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
299 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
300 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
301 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
302
303 try testCos(&.{f16});
304 try comptime testCos(&.{f16});
305}
306
307test "@cos f32/f64" {
308 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
309 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
310 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
311 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
312 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
313
314 try testCos(&.{ f32, f64 });
315 try comptime testCos(&.{ f32, f64 });
316}
317
318test "@cos f80/f128/c_longdouble" {
274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO319 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
276 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO321 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
277 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;322 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
323 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
278324
279 try comptime testCos();325 try testCos(&.{ f80, f128, c_longdouble });
280 try testCos();326 try comptime testCos(&.{ f80, f128, c_longdouble });
281}327}
282328
283fn testCos() !void {329fn testCos(comptime Ts: []const type) !void {
284 inline for ([_]type{ f16, f32, f64 }) |ty| {330 inline for (Ts) |T| {
285 const eps = epsForType(ty);331 const eps = epsForType(T);
286 try expect(@cos(@as(ty, 0)) == 1);332 var zero: T = 0;
287 try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi)), -1, eps));333 try expect(@cos(zero) == 1);
288 try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 2.0)), 0, eps));334 var pi: T = std.math.pi;
289 try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps));335 try expect(math.approxEqAbs(T, @cos(pi), -1, eps));
336 try expect(math.approxEqAbs(T, @cos(pi / 2.0), 0, eps));
337 try expect(math.approxEqAbs(T, @cos(pi / 4.0), 0.7071067811865475, eps));
290 }338 }
291}339}
292340
293test "@cos with vectors" {341test "@cos with vectors" {
294 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO342 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; // TODO343 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
297 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO344 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
298 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;345 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
346 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
299347
300 try comptime testCosWithVectors();
301 try testCosWithVectors();348 try testCosWithVectors();
349 try comptime testCosWithVectors();
302}350}
303351
304fn testCosWithVectors() !void {352fn testCosWithVectors() !void {
...@@ -310,35 +358,127 @@ fn testCosWithVectors() !void {...@@ -310,35 +358,127 @@ fn testCosWithVectors() !void {
310 try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon));358 try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon));
311}359}
312360
313test "@exp" {361test "@tan f16" {
314 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO362 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
363 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
364 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
365 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
366 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
367 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
368
369 try testTan(&.{f16});
370 try comptime testTan(&.{f16});
371}
372
373test "@tan f32/f64" {
374 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
375 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
376 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
377 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
378 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
379
380 try testTan(&.{ f32, f64 });
381 try comptime testTan(&.{ f32, f64 });
382}
383
384test "@tan f80/f128/c_longdouble" {
385 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
386 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
387 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
388 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
389 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
390
391 try testTan(&.{ f80, f128, c_longdouble });
392 try comptime testTan(&.{ f80, f128, c_longdouble });
393}
394
395fn testTan(comptime Ts: []const type) !void {
396 inline for (Ts) |T| {
397 const eps = epsForType(T);
398 var zero: T = 0;
399 try expect(@tan(zero) == 0);
400 var pi: T = std.math.pi;
401 try expect(math.approxEqAbs(T, @tan(pi), 0, eps));
402 try expect(math.approxEqAbs(T, @tan(pi / 3.0), 1.732050807568878, eps));
403 try expect(math.approxEqAbs(T, @tan(pi / 4.0), 1, eps));
404 }
405}
406
407test "@tan with vectors" {
408 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
410 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
411 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
412 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
413
414 try testTanWithVectors();
415 try comptime testTanWithVectors();
416}
417
418fn testTanWithVectors() !void {
419 var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
420 var result = @tan(v);
421 try expect(math.approxEqAbs(f32, @tan(@as(f32, 1.1)), result[0], epsilon));
422 try expect(math.approxEqAbs(f32, @tan(@as(f32, 2.2)), result[1], epsilon));
423 try expect(math.approxEqAbs(f32, @tan(@as(f32, 3.3)), result[2], epsilon));
424 try expect(math.approxEqAbs(f32, @tan(@as(f32, 4.4)), result[3], epsilon));
425}
426
427test "@exp f16" {
428 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
429 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
430 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
431 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
432 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
433 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
434
435 try testExp(&.{f16});
436 try comptime testExp(&.{f16});
437}
438
439test "@exp f32/f64" {
315 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO440 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
316 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
317 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO442 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
318 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;443 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
444 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
319445
320 try comptime testExp();446 try testExp(&.{ f32, f64 });
321 try testExp();447 try comptime testExp(&.{ f32, f64 });
322}448}
323449
324fn testExp() !void {450test "@exp f80/f128/c_longdouble" {
325 inline for ([_]type{ f16, f32, f64 }) |ty| {451 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
326 const eps = epsForType(ty);452 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
327 try expect(@exp(@as(ty, 0)) == 1);453 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
328 try expect(math.approxEqAbs(ty, @exp(@as(ty, 2)), 7.389056098930650, eps));454 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
329 try expect(math.approxEqAbs(ty, @exp(@as(ty, 5)), 148.4131591025766, eps));455 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
456
457 try testExp(&.{ f80, f128, c_longdouble });
458 try comptime testExp(&.{ f80, f128, c_longdouble });
459}
460
461fn testExp(comptime Ts: []const type) !void {
462 inline for (Ts) |T| {
463 const eps = epsForType(T);
464 var zero: T = 0;
465 try expect(@exp(zero) == 1);
466 var two: T = 2;
467 try expect(math.approxEqAbs(T, @exp(two), 7.389056098930650, eps));
468 var five: T = 5;
469 try expect(math.approxEqAbs(T, @exp(five), 148.4131591025766, eps));
330 }470 }
331}471}
332472
333test "@exp with vectors" {473test "@exp with vectors" {
334 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO474 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; // TODO475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
337 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO476 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
338 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;477 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
478 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
339479
340 try comptime testExpWithVectors();
341 try testExpWithVectors();480 try testExpWithVectors();
481 try comptime testExpWithVectors();
342}482}
343483
344fn testExpWithVectors() !void {484fn testExpWithVectors() !void {
...@@ -350,35 +490,61 @@ fn testExpWithVectors() !void {...@@ -350,35 +490,61 @@ fn testExpWithVectors() !void {
350 try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon));490 try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon));
351}491}
352492
353test "@exp2" {493test "@exp2 f16" {
354 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO494 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
495 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
496 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
497 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
498 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
499 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
500
501 try testExp2(&.{f16});
502 try comptime testExp2(&.{f16});
503}
504
505test "@exp2 f32/f64" {
506 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
509 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
510 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
511
512 try testExp2(&.{ f32, f64 });
513 try comptime testExp2(&.{ f32, f64 });
514}
515
516test "@exp2 f80/f128/c_longdouble" {
355 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO517 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
356 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO518 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
357 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO519 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
358 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;520 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
521 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
359522
360 try comptime testExp2();523 try testExp2(&.{ f80, f128, c_longdouble });
361 try testExp2();524 try comptime testExp2(&.{ f80, f128, c_longdouble });
362}525}
363526
364fn testExp2() !void {527fn testExp2(comptime Ts: []const type) !void {
365 inline for ([_]type{ f16, f32, f64 }) |ty| {528 inline for (Ts) |T| {
366 const eps = epsForType(ty);529 const eps = epsForType(T);
367 try expect(@exp2(@as(ty, 2)) == 4);530 var two: T = 2;
368 try expect(math.approxEqAbs(ty, @exp2(@as(ty, 1.5)), 2.8284271247462, eps));531 try expect(@exp2(two) == 4);
369 try expect(math.approxEqAbs(ty, @exp2(@as(ty, 4.5)), 22.627416997969, eps));532 var one_point_five: T = 1.5;
533 try expect(math.approxEqAbs(T, @exp2(one_point_five), 2.8284271247462, eps));
534 var four_point_five: T = 4.5;
535 try expect(math.approxEqAbs(T, @exp2(four_point_five), 22.627416997969, eps));
370 }536 }
371}537}
372538
373test "@exp2 with @vectors" {539test "@exp2 with @vectors" {
374 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO540 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; // TODO541 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
377 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO542 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
378 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;543 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
544 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
379545
380 try comptime testExp2WithVectors();
381 try testExp2WithVectors();546 try testExp2WithVectors();
547 try comptime testExp2WithVectors();
382}548}
383549
384fn testExp2WithVectors() !void {550fn testExp2WithVectors() !void {
...@@ -390,44 +556,59 @@ fn testExp2WithVectors() !void {...@@ -390,44 +556,59 @@ fn testExp2WithVectors() !void {
390 try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));556 try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));
391}557}
392558
393test "@log" {559test "@log f16" {
394 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
395 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO560 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
396 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO561 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
397 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO562 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;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 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
399566
400 try comptime testLog();567 try testLog(&.{f16});
401 try testLog();568 try comptime testLog(&.{f16});
402}569}
403570
404fn testLog() !void {571test "@log f32/f64" {
405 {572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
406 var a: f16 = e;573 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
407 try expect(math.approxEqAbs(f16, @log(a), 1, epsilon));574 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
408 }575 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
409 {576 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
410 var a: f32 = e;577
411 try expect(@log(a) == 1 or @log(a) == @as(f32, @bitCast(@as(u32, 0x3f7fffff))));578 try testLog(&.{ f32, f64 });
412 }579 try comptime testLog(&.{ f32, f64 });
413 {580}
414 var a: f64 = e;581
415 try expect(@log(a) == 1 or @log(a) == @as(f64, @bitCast(@as(u64, 0x3ff0000000000000))));582test "@log f80/f128/c_longdouble" {
416 }583 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
417 inline for ([_]type{ f16, f32, f64 }) |ty| {584 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
418 const eps = epsForType(ty);585 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
419 try expect(math.approxEqAbs(ty, @log(@as(ty, 2)), 0.6931471805599, eps));586 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
420 try expect(math.approxEqAbs(ty, @log(@as(ty, 5)), 1.6094379124341, eps));587 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
588
589 try testLog(&.{ f80, f128, c_longdouble });
590 try comptime testLog(&.{ f80, f128, c_longdouble });
591}
592
593fn testLog(comptime Ts: []const type) !void {
594 inline for (Ts) |T| {
595 const eps = epsForType(T);
596 var e: T = std.math.e;
597 try expect(math.approxEqAbs(T, @log(e), 1, eps));
598 var two: T = 2;
599 try expect(math.approxEqAbs(T, @log(two), 0.6931471805599, eps));
600 var five: T = 5;
601 try expect(math.approxEqAbs(T, @log(five), 1.6094379124341, eps));
421 }602 }
422}603}
423604
424test "@log with @vectors" {605test "@log with @vectors" {
425 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO606 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; // TODO607 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
428 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO608 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
429 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO609 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
430 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;610 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
611 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
431612
432 {613 {
433 var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };614 var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
...@@ -439,29 +620,54 @@ test "@log with @vectors" {...@@ -439,29 +620,54 @@ test "@log with @vectors" {
439 }620 }
440}621}
441622
442test "@log2" {623test "@log2 f16" {
443 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO624 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
625 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
626 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
627 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
628 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
629 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
630
631 try testLog2(&.{f16});
632 try comptime testLog2(&.{f16});
633}
634
635test "@log2 f32/f64" {
636 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
637 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
638 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
639 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
640 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
641
642 try testLog2(&.{ f32, f64 });
643 try comptime testLog2(&.{ f32, f64 });
644}
645
646test "@log2 f80/f128/c_longdouble" {
444 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO647 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
445 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO648 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
446 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO649 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
447 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;650 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
651 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
448652
449 try comptime testLog2();653 try testLog2(&.{ f80, f128, c_longdouble });
450 try testLog2();654 try comptime testLog2(&.{ f80, f128, c_longdouble });
451}655}
452656
453fn testLog2() !void {657fn testLog2(comptime Ts: []const type) !void {
454 inline for ([_]type{ f16, f32, f64 }) |ty| {658 inline for (Ts) |T| {
455 const eps = epsForType(ty);659 const eps = epsForType(T);
456 try expect(@log2(@as(ty, 4)) == 2);660 var four: T = 4;
457 try expect(math.approxEqAbs(ty, @log2(@as(ty, 6)), 2.5849625007212, eps));661 try expect(@log2(four) == 2);
458 try expect(math.approxEqAbs(ty, @log2(@as(ty, 10)), 3.3219280948874, eps));662 var six: T = 6;
663 try expect(math.approxEqAbs(T, @log2(six), 2.5849625007212, eps));
664 var ten: T = 10;
665 try expect(math.approxEqAbs(T, @log2(ten), 3.3219280948874, eps));
459 }666 }
460}667}
461668
462test "@log2 with vectors" {669test "@log2 with vectors" {
463 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO670 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; // TODO671 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO672 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
467 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;673 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
...@@ -469,9 +675,10 @@ test "@log2 with vectors" {...@@ -469,9 +675,10 @@ test "@log2 with vectors" {
469 if (builtin.zig_backend == .stage2_llvm and675 if (builtin.zig_backend == .stage2_llvm and
470 builtin.cpu.arch == .aarch64 and676 builtin.cpu.arch == .aarch64 and
471 builtin.os.tag == .windows) return error.SkipZigTest;677 builtin.os.tag == .windows) return error.SkipZigTest;
678 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
472679
473 try comptime testLog2WithVectors();
474 try testLog2WithVectors();680 try testLog2WithVectors();
681 try comptime testLog2WithVectors();
475}682}
476683
477fn testLog2WithVectors() !void {684fn testLog2WithVectors() !void {
...@@ -483,35 +690,61 @@ fn testLog2WithVectors() !void {...@@ -483,35 +690,61 @@ fn testLog2WithVectors() !void {
483 try expect(@log2(@as(f32, 0.4)) == result[3]);690 try expect(@log2(@as(f32, 0.4)) == result[3]);
484}691}
485692
486test "@log10" {693test "@log10 f16" {
487 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO694 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
695 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
696 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
697 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
698 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
699 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
700
701 try testLog10(&.{f16});
702 try comptime testLog10(&.{f16});
703}
704
705test "@log10 f32/f64" {
488 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
489 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO707 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
490 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO708 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
491 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;709 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
710 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
492711
493 try comptime testLog10();712 try testLog10(&.{ f32, f64 });
494 try testLog10();713 try comptime testLog10(&.{ f32, f64 });
495}714}
496715
497fn testLog10() !void {716test "@log10 f80/f128/c_longdouble" {
498 inline for ([_]type{ f16, f32, f64 }) |ty| {717 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
499 const eps = epsForType(ty);718 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
500 try expect(@log10(@as(ty, 100)) == 2);719 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
501 try expect(math.approxEqAbs(ty, @log10(@as(ty, 15)), 1.176091259056, eps));720 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
502 try expect(math.approxEqAbs(ty, @log10(@as(ty, 50)), 1.698970004336, eps));721 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
722
723 try testLog10(&.{ f80, f128, c_longdouble });
724 try comptime testLog10(&.{ f80, f128, c_longdouble });
725}
726
727fn testLog10(comptime Ts: []const type) !void {
728 inline for (Ts) |T| {
729 const eps = epsForType(T);
730 var hundred: T = 100;
731 try expect(@log10(hundred) == 2);
732 var fifteen: T = 15;
733 try expect(math.approxEqAbs(T, @log10(fifteen), 1.176091259056, eps));
734 var fifty: T = 50;
735 try expect(math.approxEqAbs(T, @log10(fifty), 1.698970004336, eps));
503 }736 }
504}737}
505738
506test "@log10 with vectors" {739test "@log10 with vectors" {
507 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO740 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; // TODO741 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
510 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO742 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
511 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;743 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
744 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
512745
513 try comptime testLog10WithVectors();
514 try testLog10WithVectors();746 try testLog10WithVectors();
747 try comptime testLog10WithVectors();
515}748}
516749
517fn testLog10WithVectors() !void {750fn testLog10WithVectors() !void {
...@@ -528,8 +761,8 @@ test "@abs" {...@@ -528,8 +761,8 @@ test "@abs" {
528 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO761 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
529 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO762 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
530763
531 try comptime testFabs();
532 try testFabs();764 try testFabs();
765 try comptime testFabs();
533}766}
534767
535fn testFabs() !void {768fn testFabs() !void {
...@@ -556,8 +789,8 @@ test "@abs with vectors" {...@@ -556,8 +789,8 @@ test "@abs with vectors" {
556 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO789 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
557 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;790 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
558791
559 try comptime testFabsWithVectors();
560 try testFabsWithVectors();792 try testFabsWithVectors();
793 try comptime testFabsWithVectors();
561}794}
562795
563fn testFabsWithVectors() !void {796fn testFabsWithVectors() !void {
...@@ -573,9 +806,9 @@ test "another, possibly redundant, @abs test" {...@@ -573,9 +806,9 @@ test "another, possibly redundant, @abs test" {
573 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO806 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
574 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO807 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
575 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
576 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
577 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;809 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
578 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;810 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
811 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
579812
580 try testFabsLegacy(f128, 12.0);813 try testFabsLegacy(f128, 12.0);
581 try comptime testFabsLegacy(f128, 12.0);814 try comptime testFabsLegacy(f128, 12.0);
...@@ -596,9 +829,9 @@ test "@abs f80" {...@@ -596,9 +829,9 @@ test "@abs f80" {
596 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO829 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
597 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO830 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
598 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO831 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
599 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
600 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;832 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
601 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;833 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
834 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
602835
603 try testFabsLegacy(f80, 12.0);836 try testFabsLegacy(f80, 12.0);
604 try comptime testFabsLegacy(f80, 12.0);837 try comptime testFabsLegacy(f80, 12.0);
...@@ -614,9 +847,9 @@ test "a third @abs test, surely there should not be three fabs tests" {...@@ -614,9 +847,9 @@ test "a third @abs test, surely there should not be three fabs tests" {
614 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO847 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
615 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO848 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
616 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO849 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;850 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;851 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
852 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
620853
621 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {854 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
622 // normals855 // normals
...@@ -645,8 +878,8 @@ test "@floor" {...@@ -645,8 +878,8 @@ test "@floor" {
645 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO878 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
646 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO879 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
647880
648 try comptime testFloor();
649 try testFloor();881 try testFloor();
882 try comptime testFloor();
650}883}
651884
652fn testFloor() !void {885fn testFloor() !void {
...@@ -664,14 +897,14 @@ fn testFloor() !void {...@@ -664,14 +897,14 @@ fn testFloor() !void {
664897
665test "@floor with vectors" {898test "@floor with vectors" {
666 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO899 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; // TODO900 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
670 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO901 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
671 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;902 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
903 if (builtin.zig_backend == .stage2_x86_64 and
904 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
672905
673 try comptime testFloorWithVectors();
674 try testFloorWithVectors();906 try testFloorWithVectors();
907 try comptime testFloorWithVectors();
675}908}
676909
677fn testFloorWithVectors() !void {910fn testFloorWithVectors() !void {
...@@ -686,8 +919,8 @@ fn testFloorWithVectors() !void {...@@ -686,8 +919,8 @@ fn testFloorWithVectors() !void {
686test "another, possibly redundant, @floor test" {919test "another, possibly redundant, @floor test" {
687 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO920 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
688 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO921 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;922 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
923 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
691924
692 try testFloorLegacy(f64, 12.0);925 try testFloorLegacy(f64, 12.0);
693 try comptime testFloorLegacy(f64, 12.0);926 try comptime testFloorLegacy(f64, 12.0);
...@@ -705,9 +938,9 @@ test "another, possibly redundant, @floor test" {...@@ -705,9 +938,9 @@ test "another, possibly redundant, @floor test" {
705test "@floor f80" {938test "@floor f80" {
706 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO939 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
707 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO940 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
708 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
709 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;941 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;942 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
943 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
711944
712 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {945 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
713 // https://github.com/ziglang/zig/issues/12602946 // https://github.com/ziglang/zig/issues/12602
...@@ -721,9 +954,9 @@ test "@floor f80" {...@@ -721,9 +954,9 @@ test "@floor f80" {
721test "@floor f128" {954test "@floor f128" {
722 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO955 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
723 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO956 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
724 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
725 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;957 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
726 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;958 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
959 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
727960
728 try testFloorLegacy(f128, 12.0);961 try testFloorLegacy(f128, 12.0);
729 try comptime testFloorLegacy(f128, 12.0);962 try comptime testFloorLegacy(f128, 12.0);
...@@ -740,8 +973,8 @@ test "@ceil" {...@@ -740,8 +973,8 @@ test "@ceil" {
740 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO973 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
741 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO974 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
742975
743 try comptime testCeil();
744 try testCeil();976 try testCeil();
977 try comptime testCeil();
745}978}
746979
747fn testCeil() !void {980fn testCeil() !void {
...@@ -759,14 +992,14 @@ fn testCeil() !void {...@@ -759,14 +992,14 @@ fn testCeil() !void {
759992
760test "@ceil with vectors" {993test "@ceil with vectors" {
761 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO994 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; // TODO995 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
765 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO996 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
766 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;997 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
998 if (builtin.zig_backend == .stage2_x86_64 and
999 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
7671000
768 try comptime testCeilWithVectors();
769 try testCeilWithVectors();1001 try testCeilWithVectors();
1002 try comptime testCeilWithVectors();
770}1003}
7711004
772fn testCeilWithVectors() !void {1005fn testCeilWithVectors() !void {
...@@ -781,8 +1014,8 @@ fn testCeilWithVectors() !void {...@@ -781,8 +1014,8 @@ fn testCeilWithVectors() !void {
781test "another, possibly redundant, @ceil test" {1014test "another, possibly redundant, @ceil test" {
782 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1015 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
783 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1016 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;1017 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1018 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7861019
787 try testCeilLegacy(f64, 12.0);1020 try testCeilLegacy(f64, 12.0);
788 try comptime testCeilLegacy(f64, 12.0);1021 try comptime testCeilLegacy(f64, 12.0);
...@@ -800,9 +1033,9 @@ test "another, possibly redundant, @ceil test" {...@@ -800,9 +1033,9 @@ test "another, possibly redundant, @ceil test" {
800test "@ceil f80" {1033test "@ceil f80" {
801 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1034 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
802 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
803 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
804 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1036 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;1037 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1038 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8061039
807 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {1040 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
808 // https://github.com/ziglang/zig/issues/126021041 // https://github.com/ziglang/zig/issues/12602
...@@ -816,9 +1049,9 @@ test "@ceil f80" {...@@ -816,9 +1049,9 @@ test "@ceil f80" {
816test "@ceil f128" {1049test "@ceil f128" {
817 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1050 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
818 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1051 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
819 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
820 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1052 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
821 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;1053 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1054 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8221055
823 try testCeilLegacy(f128, 12.0);1056 try testCeilLegacy(f128, 12.0);
824 try comptime testCeilLegacy(f128, 12.0);1057 try comptime testCeilLegacy(f128, 12.0);
...@@ -835,8 +1068,8 @@ test "@trunc" {...@@ -835,8 +1068,8 @@ test "@trunc" {
835 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1068 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
836 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1069 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8371070
838 try comptime testTrunc();
839 try testTrunc();1071 try testTrunc();
1072 try comptime testTrunc();
840}1073}
8411074
842fn testTrunc() !void {1075fn testTrunc() !void {
...@@ -854,14 +1087,14 @@ fn testTrunc() !void {...@@ -854,14 +1087,14 @@ fn testTrunc() !void {
8541087
855test "@trunc with vectors" {1088test "@trunc with vectors" {
856 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1089 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; // TODO1090 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
860 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1091 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
861 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1092 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1093 if (builtin.zig_backend == .stage2_x86_64 and
1094 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
8621095
863 try comptime testTruncWithVectors();
864 try testTruncWithVectors();1096 try testTruncWithVectors();
1097 try comptime testTruncWithVectors();
865}1098}
8661099
867fn testTruncWithVectors() !void {1100fn testTruncWithVectors() !void {
...@@ -876,8 +1109,8 @@ fn testTruncWithVectors() !void {...@@ -876,8 +1109,8 @@ fn testTruncWithVectors() !void {
876test "another, possibly redundant, @trunc test" {1109test "another, possibly redundant, @trunc test" {
877 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1110 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
878 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1111 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;1112 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1113 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8811114
882 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {1115 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
883 // https://github.com/ziglang/zig/issues/168461116 // https://github.com/ziglang/zig/issues/16846
...@@ -900,9 +1133,9 @@ test "another, possibly redundant, @trunc test" {...@@ -900,9 +1133,9 @@ test "another, possibly redundant, @trunc test" {
900test "@trunc f80" {1133test "@trunc f80" {
901 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1134 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
902 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1135 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;1136 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;1137 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1138 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
9061139
907 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {1140 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
908 // https://github.com/ziglang/zig/issues/126021141 // https://github.com/ziglang/zig/issues/12602
...@@ -922,9 +1155,9 @@ test "@trunc f80" {...@@ -922,9 +1155,9 @@ test "@trunc f80" {
922test "@trunc f128" {1155test "@trunc f128" {
923 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1156 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
924 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1157 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;1158 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;1159 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1160 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
9281161
929 try testTruncLegacy(f128, 12.0);1162 try testTruncLegacy(f128, 12.0);
930 try comptime testTruncLegacy(f128, 12.0);1163 try comptime testTruncLegacy(f128, 12.0);
...@@ -945,11 +1178,11 @@ fn testTruncLegacy(comptime T: type, x: T) !void {...@@ -945,11 +1178,11 @@ fn testTruncLegacy(comptime T: type, x: T) !void {
945}1178}
9461179
947test "negation f16" {1180test "negation f16" {
948 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
949 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
950 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
951 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
952 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1184 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1185 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
9531186
954 if (builtin.os.tag == .freebsd) {1187 if (builtin.os.tag == .freebsd) {
955 // TODO file issue to track this failure1188 // TODO file issue to track this failure
...@@ -1011,11 +1244,11 @@ test "negation f64" {...@@ -1011,11 +1244,11 @@ test "negation f64" {
1011}1244}
10121245
1013test "negation f80" {1246test "negation f80" {
1014 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1015 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1016 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1248 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1017 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1249 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1018 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1250 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1251 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10191252
1020 const S = struct {1253 const S = struct {
1021 fn doTheTest() !void {1254 fn doTheTest() !void {
...@@ -1032,11 +1265,11 @@ test "negation f80" {...@@ -1032,11 +1265,11 @@ test "negation f80" {
1032}1265}
10331266
1034test "negation f128" {1267test "negation f128" {
1035 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1036 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1268 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1037 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1038 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1270 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1039 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1271 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1272 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10401273
1041 const S = struct {1274 const S = struct {
1042 fn doTheTest() !void {1275 fn doTheTest() !void {
...@@ -1075,11 +1308,11 @@ test "f128 at compile time is lossy" {...@@ -1075,11 +1308,11 @@ test "f128 at compile time is lossy" {
1075}1308}
10761309
1077test "comptime fixed-width float zero divided by zero produces NaN" {1310test "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; // TODO1311 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1080 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1081 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1082 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1314 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1315 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10831316
1084 inline for (.{ f16, f32, f64, f80, f128 }) |F| {1317 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
1085 try expect(math.isNan(@as(F, 0) / @as(F, 0)));1318 try expect(math.isNan(@as(F, 0) / @as(F, 0)));
...@@ -1182,11 +1415,11 @@ test "nan negation f128" {...@@ -1182,11 +1415,11 @@ test "nan negation f128" {
1182}1415}
11831416
1184test "nan negation f80" {1417test "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; // TODO1418 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1187 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1419 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1188 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1189 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1421 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1422 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
11901423
1191 const nan_comptime = comptime math.nan(f80);1424 const nan_comptime = comptime math.nan(f80);
1192 const neg_nan_comptime = -nan_comptime;1425 const neg_nan_comptime = -nan_comptime;
test/behavior/math.zig+18-9
...@@ -7,6 +7,8 @@ const maxInt = std.math.maxInt;...@@ -7,6 +7,8 @@ const maxInt = std.math.maxInt;
7const minInt = std.math.minInt;7const minInt = std.math.minInt;
8const mem = std.mem;8const mem = std.mem;
9const math = std.math;9const math = std.math;
10const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and
11 !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c);
1012
11test "assignment operators" {13test "assignment operators" {
12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1437,19 +1439,29 @@ fn fmodOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {...@@ -1437,19 +1439,29 @@ 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);1439 try expect(@abs(@mod(@as(T, a), @as(T, b)) - @as(T, c)) < epsilon);
1438}1440}
14391441
1440test "@round" {1442test "@round f16" {
1443 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1444 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1445 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1446 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1447 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
1448 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
1449
1450 try testRound(f16, 12.0);
1451 try comptime testRound(f16, 12.0);
1452}
1453
1454test "@round f32/f64" {
1441 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1455 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1456 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; // TODO1457 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1445 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1458 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1459 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
14461460
1447 try testRound(f64, 12.0);1461 try testRound(f64, 12.0);
1448 try comptime testRound(f64, 12.0);1462 try comptime testRound(f64, 12.0);
1449 try testRound(f32, 12.0);1463 try testRound(f32, 12.0);
1450 try comptime testRound(f32, 12.0);1464 try comptime testRound(f32, 12.0);
1451 try testRound(f16, 12.0);
1452 try comptime testRound(f16, 12.0);
14531465
1454 const x = 14.0;1466 const x = 14.0;
1455 const y = x + 0.4;1467 const y = x + 0.4;
...@@ -1464,6 +1476,7 @@ test "@round f80" {...@@ -1464,6 +1476,7 @@ test "@round f80" {
1464 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1465 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1477 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;1478 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1479 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
14671480
1468 try testRound(f80, 12.0);1481 try testRound(f80, 12.0);
1469 try comptime testRound(f80, 12.0);1482 try comptime testRound(f80, 12.0);
...@@ -1476,6 +1489,7 @@ test "@round f128" {...@@ -1476,6 +1489,7 @@ test "@round f128" {
1476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1489 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1477 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1490 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;1491 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
1492 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
14791493
1480 try testRound(f128, 12.0);1494 try testRound(f128, 12.0);
1481 try comptime testRound(f128, 12.0);1495 try comptime testRound(f128, 12.0);
...@@ -1608,11 +1622,6 @@ test "signed zeros are represented properly" {...@@ -1608,11 +1622,6 @@ test "signed zeros are represented properly" {
1608 try comptime S.doTheTest();1622 try comptime S.doTheTest();
1609}1623}
16101624
1611test "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
1616test "absFloat" {1625test "absFloat" {
1617 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1626 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1618 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1627 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO