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 {
18711871 comp.job_queued_compiler_rt_lib = true;
18721872 } else if (options.output_mode != .Obj) {
18731873 log.debug("queuing a job to build compiler_rt_obj", .{});
1874 // If build-obj with -fcompiler-rt is requested, that is handled specially
1875 // elsewhere. In this case we are making a static library, so we ask
1874 // In this case we are making a static library, so we ask
18761875 // for a compiler-rt object to put in it.
18771876 comp.job_queued_compiler_rt_obj = true;
18781877 }
src/InternPool.zig+10-15
......@@ -5407,19 +5407,19 @@ pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeIni
54075407
54085408/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.
54095409pub const GetFuncTypeKey = struct {
5410 param_types: []Index,
5410 param_types: []const Index,
54115411 return_type: Index,
5412 comptime_bits: u32,
5413 noalias_bits: u32,
5412 comptime_bits: u32 = 0,
5413 noalias_bits: u32 = 0,
54145414 /// `null` means generic.
5415 alignment: ?Alignment,
5415 alignment: ?Alignment = .none,
54165416 /// `null` means generic.
5417 cc: ?std.builtin.CallingConvention,
5418 is_var_args: bool,
5419 is_generic: bool,
5420 is_noinline: bool,
5421 section_is_generic: bool,
5422 addrspace_is_generic: bool,
5417 cc: ?std.builtin.CallingConvention = .Unspecified,
5418 is_var_args: bool = false,
5419 is_generic: bool = false,
5420 is_noinline: bool = false,
5421 section_is_generic: bool = false,
5422 addrspace_is_generic: bool = false,
54235423};
54245424
54255425pub fn getFuncType(ip: *InternPool, gpa: Allocator, key: GetFuncTypeKey) Allocator.Error!Index {
......@@ -5754,15 +5754,10 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
57545754 const func_ty = try ip.getFuncType(gpa, .{
57555755 .param_types = arg.param_types,
57565756 .return_type = arg.bare_return_type,
5757 .comptime_bits = 0,
57585757 .noalias_bits = arg.noalias_bits,
57595758 .alignment = arg.alignment,
57605759 .cc = arg.cc,
5761 .is_var_args = false,
5762 .is_generic = false,
57635760 .is_noinline = arg.is_noinline,
5764 .section_is_generic = false,
5765 .addrspace_is_generic = false,
57665761 });
57675762
57685763 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
src/Sema.zig+3-8
......@@ -7373,10 +7373,10 @@ fn analyzeCall(
73737373 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
73747374
73757375 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);
73767377 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,
73787379 .return_type = owner_info.return_type,
7379 .comptime_bits = 0,
73807380 .noalias_bits = owner_info.noalias_bits,
73817381 .alignment = if (owner_info.align_is_generic) null else owner_info.alignment,
73827382 .cc = if (owner_info.cc_is_generic) null else owner_info.cc,
......@@ -7403,7 +7403,7 @@ fn analyzeCall(
74037403 block,
74047404 &child_block,
74057405 inst,
7406 new_fn_info.param_types,
7406 new_param_types,
74077407 &arg_i,
74087408 args_info,
74097409 is_comptime_call,
......@@ -21144,16 +21144,11 @@ fn zirReify(
2114421144
2114521145 const ty = try mod.funcType(.{
2114621146 .param_types = param_types,
21147 .comptime_bits = 0,
2114821147 .noalias_bits = noalias_bits,
2114921148 .return_type = return_type.toIntern(),
2115021149 .alignment = alignment,
2115121150 .cc = cc,
2115221151 .is_var_args = is_var_args,
21153 .is_generic = false,
21154 .is_noinline = false,
21155 .section_is_generic = false,
21156 .addrspace_is_generic = false,
2115721152 });
2115821153 return Air.internedToRef(ty.toIntern());
2115921154 },
src/arch/x86_64/CodeGen.zig+182-138
......@@ -1807,7 +1807,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
18071807 .log2,
18081808 .log10,
18091809 .round,
1810 => try self.airUnaryMath(inst),
1810 => |tag| try self.airUnaryMath(inst, tag),
18111811
18121812 .floor => try self.airRound(inst, 0b1_0_01),
18131813 .ceil => try self.airRound(inst, 0b1_0_10),
......@@ -5280,13 +5280,35 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
52805280 return self.finishAir(inst, result, .{ un_op, .none, .none });
52815281}
52825282
5283fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {
5283fn airUnaryMath(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
52845284 const un_op = self.air.instructions.items(.data)[inst].un_op;
5285 _ = un_op;
5286 return self.fail("TODO implement airUnaryMath for {}", .{
5287 self.air.instructions.items(.tag)[inst],
5288 });
5289 //return self.finishAir(inst, result, .{ un_op, .none, .none });
5285 const ty = self.typeOf(un_op).toIntern();
5286 const result = try self.genCall(.{ .lib = .{
5287 .return_type = ty,
5288 .param_types = &.{ty},
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 });
52905312}
52915313
52925314fn reuseOperand(
......@@ -7290,7 +7312,7 @@ fn genBinOp(
72907312
72917313 switch (air_tag) {
72927314 .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(
72947316 lhs_ty,
72957317 dst_reg,
72967318 .{ .register = dst_reg },
......@@ -7299,9 +7321,7 @@ fn genBinOp(
72997321 .div_floor => 0b1_0_01,
73007322 else => unreachable,
73017323 },
7302 ) else return self.fail("TODO implement genBinOp for {s} {} without sse4_1 feature", .{
7303 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
7304 }),
7324 ),
73057325 .bit_and, .bit_or, .xor => {},
73067326 .max, .min => if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx)) {
73077327 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
......@@ -8124,31 +8144,59 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {
81248144}
81258145
81268146fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
8127 const mod = self.bin_file.options.module.?;
81288147 if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{});
8148
81298149 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8130 const callee = pl_op.operand;
81318150 const extra = self.air.extraData(Air.Call, pl_op.payload);
81328151 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)) {
8136 .Fn => ty,
8137 .Pointer => ty.childType(mod),
8138 else => unreachable,
8139 };
8153 const ret = try self.genCall(.{ .air = pl_op.operand }, args);
8154
8155 var bt = self.liveness.iterateBigTomb(inst);
8156 self.feed(&bt, pl_op.operand);
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 };
81418189 const fn_info = mod.typeToFunc(fn_ty).?;
81428190
8143 var info = try self.resolveCallingConventionValues(fn_info, args[fn_info.param_types.len..], .call_frame);
8144 defer info.deinit(self);
8191 var call_info =
8192 try self.resolveCallingConventionValues(fn_info, args[fn_info.param_types.len..], .call_frame);
8193 defer call_info.deinit(self);
81458194
81468195 // We need a properly aligned and sized call frame to be able to call this function.
81478196 {
8148 const needed_call_frame =
8149 FrameAlloc.init(.{
8150 .size = info.stack_byte_count,
8151 .alignment = info.stack_align,
8197 const needed_call_frame = FrameAlloc.init(.{
8198 .size = call_info.stack_byte_count,
8199 .alignment = call_info.stack_align,
81528200 });
81538201 const frame_allocs_slice = self.frame_allocs.slice();
81548202 const stack_frame_size =
......@@ -8164,24 +8212,20 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81648212
81658213 // set stack arguments first because this can clobber registers
81668214 // also clobber spill arguments as we go
8167 switch (info.return_value.long) {
8215 switch (call_info.return_value.long) {
81688216 .none, .unreach => {},
81698217 .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}),
81708218 else => unreachable,
81718219 }
8172 for (args, info.args) |arg, mc_arg| {
8173 const arg_ty = self.typeOf(arg);
8174 const arg_mcv = try self.resolveInst(arg);
8175 switch (mc_arg) {
8176 .none => {},
8177 .register => |reg| try self.spillRegisters(&.{reg}),
8178 .load_frame => try self.genCopy(arg_ty, mc_arg, arg_mcv),
8179 else => unreachable,
8180 }
8181 }
8220 for (call_info.args, args) |dst_arg, src_arg| switch (dst_arg) {
8221 .none => {},
8222 .register => |reg| try self.spillRegisters(&.{reg}),
8223 .load_frame => try self.genCopy(self.typeOf(src_arg), dst_arg, try self.resolveInst(src_arg)),
8224 else => unreachable,
8225 };
81828226
81838227 // 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) {
81858229 .none, .unreach => null,
81868230 .indirect => |reg_off| lock: {
81878231 const ret_ty = fn_info.return_type.toType();
......@@ -8189,125 +8233,80 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81898233 try self.genSetReg(reg_off.reg, Type.usize, .{
81908234 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
81918235 });
8192 info.return_value.short = .{ .load_frame = .{ .index = frame_index } };
8236 call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } };
81938237 break :lock self.register_manager.lockRegAssumeUnused(reg_off.reg);
81948238 },
81958239 else => unreachable,
81968240 };
81978241 defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);
81988242
8199 for (args, info.args) |arg, mc_arg| {
8200 const arg_ty = self.typeOf(arg);
8201 const arg_mcv = try self.resolveInst(arg);
8202 switch (mc_arg) {
8243 for (call_info.args, args) |dst_arg, src_arg| {
8244 switch (dst_arg) {
82038245 .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)),
82058247 else => unreachable,
82068248 }
82078249 }
82088250
82098251 // Due to incremental compilation, how function calls are generated depends
82108252 // on linking.
8211 if (try self.air.value(callee, mod)) |func_value| {
8212 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);
8213 if (switch (func_key) {
8214 .func => |func| func.owner_decl,
8215 .ptr => |ptr| switch (ptr.addr) {
8216 .decl => |decl| decl,
8253 switch (info) {
8254 .air => |callee| if (try self.air.value(callee, mod)) |func_value| {
8255 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);
8256 if (switch (func_key) {
8257 .func => |func| func.owner_decl,
8258 .ptr => |ptr| switch (ptr.addr) {
8259 .decl => |decl| decl,
8260 else => null,
8261 },
82178262 else => null,
8218 },
8219 else => null,
8220 }) |owner_decl| {
8221 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8222 const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl);
8223 const sym = elf_file.symbol(sym_index);
8224 sym.flags.needs_got = true;
8225 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);
8226 _ = try self.addInst(.{
8227 .tag = .call,
8228 .ops = .direct_got_reloc,
8229 .data = .{ .reloc = .{
8230 .atom_index = try self.owner.getSymbolIndex(self),
8231 .sym_index = sym.esym_index,
8232 } },
8233 });
8234 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8235 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);
8236 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
8237 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8238 try self.asmRegister(.{ ._, .call }, .rax);
8239 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8240 const atom = try macho_file.getOrCreateAtomForDecl(owner_decl);
8241 const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
8242 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8243 try self.asmRegister(.{ ._, .call }, .rax);
8244 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
8245 const atom_index = try p9.seeDecl(owner_decl);
8246 const atom = p9.getAtom(atom_index);
8247 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
8248 .base = .{ .reg = .ds },
8249 .disp = @intCast(atom.getOffsetTableAddress(p9)),
8250 }));
8251 } else unreachable;
8252 } else if (func_value.getExternFunc(mod)) |extern_func| {
8253 const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.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 });
8263 }) |owner_decl| {
8264 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8265 const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl);
8266 const sym = elf_file.symbol(sym_index);
8267 sym.flags.needs_got = true;
8268 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);
8269 _ = try self.addInst(.{
8270 .tag = .call,
8271 .ops = .direct_got_reloc,
8272 .data = .{ .reloc = .{
8273 .atom_index = try self.owner.getSymbolIndex(self),
8274 .sym_index = sym.esym_index,
8275 } },
8276 });
8277 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8278 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);
8279 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
8280 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8281 try self.asmRegister(.{ ._, .call }, .rax);
8282 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8283 const atom = try macho_file.getOrCreateAtomForDecl(owner_decl);
8284 const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
8285 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8286 try self.asmRegister(.{ ._, .call }, .rax);
8287 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
8288 const atom_index = try p9.seeDecl(owner_decl);
8289 const atom = p9.getAtom(atom_index);
8290 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{
8291 .base = .{ .reg = .ds },
8292 .disp = @intCast(atom.getOffsetTableAddress(p9)),
8293 }));
8294 } else unreachable;
8295 } else if (func_value.getExternFunc(mod)) |extern_func| {
8296 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
8297 const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name);
8298 try self.genExternSymbolRef(.call, lib_name, decl_name);
82928299 } else {
8293 return self.fail("TODO implement calling extern functions", .{});
8300 return self.fail("TODO implement calling bitcasted functions", .{});
82948301 }
82958302 } else {
8296 return self.fail("TODO implement calling bitcasted functions", .{});
8297 }
8298 } else {
8299 assert(ty.zigTypeTag(mod) == .Pointer);
8300 const mcv = try self.resolveInst(callee);
8301 try self.genSetReg(.rax, Type.usize, mcv);
8302 try self.asmRegister(.{ ._, .call }, .rax);
8303 assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer);
8304 try self.genSetReg(.rax, Type.usize, try self.resolveInst(callee));
8305 try self.asmRegister(.{ ._, .call }, .rax);
8306 },
8307 .lib => |lib| try self.genExternSymbolRef(.call, lib.lib, lib.callee),
83038308 }
8304
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);
8309 return call_info.return_value.short;
83118310}
83128311
83138312fn airRet(self: *Self, inst: Air.Inst.Index) !void {
......@@ -10281,6 +10280,51 @@ fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue)
1028110280 try self.asmOpOnly(.{ .@"rep _sb", .sto });
1028210281}
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
1028410328fn genLazySymbolRef(
1028510329 self: *Self,
1028610330 comptime tag: Mir.Inst.Tag,
src/codegen/llvm.zig-9
......@@ -6394,15 +6394,6 @@ pub const FuncGen = struct {
63946394 const fn_ty = try mod.funcType(.{
63956395 .param_types = &.{},
63966396 .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,
64066397 });
64076398 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);
64086399 const subprogram = dib.createFunction(
test/behavior/floatop.zig+382-149
......@@ -2,8 +2,6 @@ const std = @import("std");
22const builtin = @import("builtin");
33const expect = std.testing.expect;
44const math = std.math;
5const pi = std.math.pi;
6const e = std.math.e;
75const has_f80_rt = switch (builtin.cpu.arch) {
86 .x86_64, .x86 => true,
97 else => false,
......@@ -11,7 +9,7 @@ const has_f80_rt = switch (builtin.cpu.arch) {
119const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and
1210 !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c);
1311
14const epsilon_16 = 0.001;
12const epsilon_16 = 0.002;
1513const epsilon = 0.000001;
1614
1715fn epsForType(comptime T: type) T {
......@@ -29,10 +27,10 @@ test "floating point comparisons" {
2927}
3028
3129fn testFloatComparisons() !void {
32 inline for ([_]type{ f16, f32, f64, f128 }) |ty| {
30 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
3331 // No decimal part
3432 {
35 const x: ty = 1.0;
33 const x: T = 1.0;
3634 try expect(x == 1);
3735 try expect(x != 0);
3836 try expect(x > 0);
......@@ -42,7 +40,7 @@ fn testFloatComparisons() !void {
4240 }
4341 // Non-zero decimal part
4442 {
45 const x: ty = 1.5;
43 const x: T = 1.5;
4644 try expect(x != 1);
4745 try expect(x != 2);
4846 try expect(x > 1);
......@@ -54,11 +52,11 @@ fn testFloatComparisons() !void {
5452}
5553
5654test "different sized float comparisons" {
57 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
5855 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5956 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6057 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
6158 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
59 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
6260
6361 try testDifferentSizedFloatComparisons();
6462 try comptime testDifferentSizedFloatComparisons();
......@@ -73,9 +71,9 @@ fn testDifferentSizedFloatComparisons() !void {
7371test "f80 comparisons" {
7472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7573 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7774 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
8078 try expect(compareF80(0.0, .eq, -0.0));
8179 try expect(compareF80(0.0, .lte, -0.0));
......@@ -125,8 +123,8 @@ test "@sqrt" {
125123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
126124 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
127125
128 try comptime testSqrt();
129126 try testSqrt();
127 try comptime testSqrt();
130128}
131129
132130fn testSqrt() !void {
......@@ -163,8 +161,8 @@ test "@sqrt with vectors" {
163161 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
164162 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
165163
166 try comptime testSqrtWithVectors();
167164 try testSqrtWithVectors();
165 try comptime testSqrtWithVectors();
168166}
169167
170168fn testSqrtWithVectors() !void {
......@@ -177,11 +175,11 @@ fn testSqrtWithVectors() !void {
177175}
178176
179177test "more @sqrt f16 tests" {
180 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
181178 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
182179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
183180 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184181 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
182 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
185183
186184 // TODO these are not all passing at comptime
187185 try expect(@sqrt(@as(f16, 0.0)) == 0.0);
......@@ -205,8 +203,8 @@ test "more @sqrt f16 tests" {
205203test "another, possibly redundant @sqrt test" {
206204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
207205 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
208 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
209206 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
207 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
210208
211209 try testSqrtLegacy(f64, 12.0);
212210 try comptime testSqrtLegacy(f64, 12.0);
......@@ -228,36 +226,61 @@ fn testSqrtLegacy(comptime T: type, x: T) !void {
228226 try expect(@sqrt(x * x) == x);
229227}
230228
231test "@sin" {
232 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
229test "@sin f16" {
230 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" {
233242 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
234243 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
235244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
236245 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();
239 try testSin();
248 try testSin(&.{ f32, f64 });
249 try comptime testSin(&.{ f32, f64 });
240250}
241251
242fn testSin() !void {
243 inline for ([_]type{ f16, f32, f64 }) |ty| {
244 const eps = epsForType(ty);
245 try expect(@sin(@as(ty, 0)) == 0);
246 try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi)), 0, eps));
247 try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 2.0)), 1, eps));
248 try expect(math.approxEqAbs(ty, @sin(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps));
252test "@sin f80/f128/c_longdouble" {
253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
257 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
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));
249272 }
250273}
251274
252275test "@sin with vectors" {
253276 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
254 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
255277 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256278 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
257279 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();
260282 try testSinWithVectors();
283 try comptime testSinWithVectors();
261284}
262285
263286fn testSinWithVectors() !void {
......@@ -269,36 +292,61 @@ fn testSinWithVectors() !void {
269292 try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon));
270293}
271294
272test "@cos" {
273 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
295test "@cos f16" {
296 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" {
274319 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
275320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
276321 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
277322 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();
280 try testCos();
325 try testCos(&.{ f80, f128, c_longdouble });
326 try comptime testCos(&.{ f80, f128, c_longdouble });
281327}
282328
283fn testCos() !void {
284 inline for ([_]type{ f16, f32, f64 }) |ty| {
285 const eps = epsForType(ty);
286 try expect(@cos(@as(ty, 0)) == 1);
287 try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi)), -1, eps));
288 try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 2.0)), 0, eps));
289 try expect(math.approxEqAbs(ty, @cos(@as(ty, std.math.pi / 4.0)), 0.7071067811865475, eps));
329fn testCos(comptime Ts: []const type) !void {
330 inline for (Ts) |T| {
331 const eps = epsForType(T);
332 var zero: T = 0;
333 try expect(@cos(zero) == 1);
334 var pi: T = std.math.pi;
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));
290338 }
291339}
292340
293341test "@cos with vectors" {
294342 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
295 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
296343 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
297344 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
298345 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();
301348 try testCosWithVectors();
349 try comptime testCosWithVectors();
302350}
303351
304352fn testCosWithVectors() !void {
......@@ -310,35 +358,127 @@ fn testCosWithVectors() !void {
310358 try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon));
311359}
312360
313test "@exp" {
314 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
361test "@tan f16" {
362 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" {
315440 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
316441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
317442 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
318443 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();
321 try testExp();
446 try testExp(&.{ f32, f64 });
447 try comptime testExp(&.{ f32, f64 });
322448}
323449
324fn testExp() !void {
325 inline for ([_]type{ f16, f32, f64 }) |ty| {
326 const eps = epsForType(ty);
327 try expect(@exp(@as(ty, 0)) == 1);
328 try expect(math.approxEqAbs(ty, @exp(@as(ty, 2)), 7.389056098930650, eps));
329 try expect(math.approxEqAbs(ty, @exp(@as(ty, 5)), 148.4131591025766, eps));
450test "@exp f80/f128/c_longdouble" {
451 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
452 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
453 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
454 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
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));
330470 }
331471}
332472
333473test "@exp with vectors" {
334474 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
335 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
336475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
337476 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
338477 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();
341480 try testExpWithVectors();
481 try comptime testExpWithVectors();
342482}
343483
344484fn testExpWithVectors() !void {
......@@ -350,35 +490,61 @@ fn testExpWithVectors() !void {
350490 try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon));
351491}
352492
353test "@exp2" {
354 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
493test "@exp2 f16" {
494 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" {
355517 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
356518 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
357519 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
358520 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();
361 try testExp2();
523 try testExp2(&.{ f80, f128, c_longdouble });
524 try comptime testExp2(&.{ f80, f128, c_longdouble });
362525}
363526
364fn testExp2() !void {
365 inline for ([_]type{ f16, f32, f64 }) |ty| {
366 const eps = epsForType(ty);
367 try expect(@exp2(@as(ty, 2)) == 4);
368 try expect(math.approxEqAbs(ty, @exp2(@as(ty, 1.5)), 2.8284271247462, eps));
369 try expect(math.approxEqAbs(ty, @exp2(@as(ty, 4.5)), 22.627416997969, eps));
527fn testExp2(comptime Ts: []const type) !void {
528 inline for (Ts) |T| {
529 const eps = epsForType(T);
530 var two: T = 2;
531 try expect(@exp2(two) == 4);
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));
370536 }
371537}
372538
373539test "@exp2 with @vectors" {
374540 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
375 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
376541 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
377542 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
378543 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();
381546 try testExp2WithVectors();
547 try comptime testExp2WithVectors();
382548}
383549
384550fn testExp2WithVectors() !void {
......@@ -390,44 +556,59 @@ fn testExp2WithVectors() !void {
390556 try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));
391557}
392558
393test "@log" {
394 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
559test "@log f16" {
395560 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
396561 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
397562 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
398563 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();
401 try testLog();
567 try testLog(&.{f16});
568 try comptime testLog(&.{f16});
402569}
403570
404fn testLog() !void {
405 {
406 var a: f16 = e;
407 try expect(math.approxEqAbs(f16, @log(a), 1, epsilon));
408 }
409 {
410 var a: f32 = e;
411 try expect(@log(a) == 1 or @log(a) == @as(f32, @bitCast(@as(u32, 0x3f7fffff))));
412 }
413 {
414 var a: f64 = e;
415 try expect(@log(a) == 1 or @log(a) == @as(f64, @bitCast(@as(u64, 0x3ff0000000000000))));
416 }
417 inline for ([_]type{ f16, f32, f64 }) |ty| {
418 const eps = epsForType(ty);
419 try expect(math.approxEqAbs(ty, @log(@as(ty, 2)), 0.6931471805599, eps));
420 try expect(math.approxEqAbs(ty, @log(@as(ty, 5)), 1.6094379124341, eps));
571test "@log f32/f64" {
572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
573 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
574 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
575 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
576 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
577
578 try testLog(&.{ f32, f64 });
579 try comptime testLog(&.{ f32, f64 });
580}
581
582test "@log f80/f128/c_longdouble" {
583 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
584 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
585 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
586 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
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));
421602 }
422603}
423604
424605test "@log with @vectors" {
425606 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
426 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
427607 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
428608 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
429609 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
430610 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
611 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
431612
432613 {
433614 var v: @Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
......@@ -439,29 +620,54 @@ test "@log with @vectors" {
439620 }
440621}
441622
442test "@log2" {
443 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
623test "@log2 f16" {
624 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" {
444647 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
445648 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
446649 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
447650 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();
450 try testLog2();
653 try testLog2(&.{ f80, f128, c_longdouble });
654 try comptime testLog2(&.{ f80, f128, c_longdouble });
451655}
452656
453fn testLog2() !void {
454 inline for ([_]type{ f16, f32, f64 }) |ty| {
455 const eps = epsForType(ty);
456 try expect(@log2(@as(ty, 4)) == 2);
457 try expect(math.approxEqAbs(ty, @log2(@as(ty, 6)), 2.5849625007212, eps));
458 try expect(math.approxEqAbs(ty, @log2(@as(ty, 10)), 3.3219280948874, eps));
657fn testLog2(comptime Ts: []const type) !void {
658 inline for (Ts) |T| {
659 const eps = epsForType(T);
660 var four: T = 4;
661 try expect(@log2(four) == 2);
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));
459666 }
460667}
461668
462669test "@log2 with vectors" {
463670 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
464 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
465671 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
466672 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
467673 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
......@@ -469,9 +675,10 @@ test "@log2 with vectors" {
469675 if (builtin.zig_backend == .stage2_llvm and
470676 builtin.cpu.arch == .aarch64 and
471677 builtin.os.tag == .windows) return error.SkipZigTest;
678 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
472679
473 try comptime testLog2WithVectors();
474680 try testLog2WithVectors();
681 try comptime testLog2WithVectors();
475682}
476683
477684fn testLog2WithVectors() !void {
......@@ -483,35 +690,61 @@ fn testLog2WithVectors() !void {
483690 try expect(@log2(@as(f32, 0.4)) == result[3]);
484691}
485692
486test "@log10" {
487 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
693test "@log10 f16" {
694 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" {
488706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
489707 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
490708 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
491709 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();
494 try testLog10();
712 try testLog10(&.{ f32, f64 });
713 try comptime testLog10(&.{ f32, f64 });
495714}
496715
497fn testLog10() !void {
498 inline for ([_]type{ f16, f32, f64 }) |ty| {
499 const eps = epsForType(ty);
500 try expect(@log10(@as(ty, 100)) == 2);
501 try expect(math.approxEqAbs(ty, @log10(@as(ty, 15)), 1.176091259056, eps));
502 try expect(math.approxEqAbs(ty, @log10(@as(ty, 50)), 1.698970004336, eps));
716test "@log10 f80/f128/c_longdouble" {
717 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
718 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
719 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
720 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
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));
503736 }
504737}
505738
506739test "@log10 with vectors" {
507740 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
509741 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
510742 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
511743 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();
514746 try testLog10WithVectors();
747 try comptime testLog10WithVectors();
515748}
516749
517750fn testLog10WithVectors() !void {
......@@ -528,8 +761,8 @@ test "@abs" {
528761 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
529762 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
530763
531 try comptime testFabs();
532764 try testFabs();
765 try comptime testFabs();
533766}
534767
535768fn testFabs() !void {
......@@ -556,8 +789,8 @@ test "@abs with vectors" {
556789 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
557790 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
558791
559 try comptime testFabsWithVectors();
560792 try testFabsWithVectors();
793 try comptime testFabsWithVectors();
561794}
562795
563796fn testFabsWithVectors() !void {
......@@ -573,9 +806,9 @@ test "another, possibly redundant, @abs test" {
573806 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
574807 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
575808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
576 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
577809 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
580813 try testFabsLegacy(f128, 12.0);
581814 try comptime testFabsLegacy(f128, 12.0);
......@@ -596,9 +829,9 @@ test "@abs f80" {
596829 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
597830 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
598831 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
599 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
600832 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
603836 try testFabsLegacy(f80, 12.0);
604837 try comptime testFabsLegacy(f80, 12.0);
......@@ -614,9 +847,9 @@ test "a third @abs test, surely there should not be three fabs tests" {
614847 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
615848 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
616849 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
617 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
618850 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
621854 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
622855 // normals
......@@ -645,8 +878,8 @@ test "@floor" {
645878 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
646879 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
647880
648 try comptime testFloor();
649881 try testFloor();
882 try comptime testFloor();
650883}
651884
652885fn testFloor() !void {
......@@ -664,14 +897,14 @@ fn testFloor() !void {
664897
665898test "@floor with vectors" {
666899 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
669900 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
670901 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
671902 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();
674906 try testFloorWithVectors();
907 try comptime testFloorWithVectors();
675908}
676909
677910fn testFloorWithVectors() !void {
......@@ -686,8 +919,8 @@ fn testFloorWithVectors() !void {
686919test "another, possibly redundant, @floor test" {
687920 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
688921 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
689 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
690922 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
923 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
691924
692925 try testFloorLegacy(f64, 12.0);
693926 try comptime testFloorLegacy(f64, 12.0);
......@@ -705,9 +938,9 @@ test "another, possibly redundant, @floor test" {
705938test "@floor f80" {
706939 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
707940 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
708 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
709941 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
712945 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
713946 // https://github.com/ziglang/zig/issues/12602
......@@ -721,9 +954,9 @@ test "@floor f80" {
721954test "@floor f128" {
722955 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
723956 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
724 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
725957 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
728961 try testFloorLegacy(f128, 12.0);
729962 try comptime testFloorLegacy(f128, 12.0);
......@@ -740,8 +973,8 @@ test "@ceil" {
740973 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
741974 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
742975
743 try comptime testCeil();
744976 try testCeil();
977 try comptime testCeil();
745978}
746979
747980fn testCeil() !void {
......@@ -759,14 +992,14 @@ fn testCeil() !void {
759992
760993test "@ceil with vectors" {
761994 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
764995 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
765996 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
766997 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();
7691001 try testCeilWithVectors();
1002 try comptime testCeilWithVectors();
7701003}
7711004
7721005fn testCeilWithVectors() !void {
......@@ -781,8 +1014,8 @@ fn testCeilWithVectors() !void {
7811014test "another, possibly redundant, @ceil test" {
7821015 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7831016 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
784 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7851017 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1018 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
7861019
7871020 try testCeilLegacy(f64, 12.0);
7881021 try comptime testCeilLegacy(f64, 12.0);
......@@ -800,9 +1033,9 @@ test "another, possibly redundant, @ceil test" {
8001033test "@ceil f80" {
8011034 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8021035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
803 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8041036 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
8071040 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
8081041 // https://github.com/ziglang/zig/issues/12602
......@@ -816,9 +1049,9 @@ test "@ceil f80" {
8161049test "@ceil f128" {
8171050 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8181051 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
819 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8201052 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
8231056 try testCeilLegacy(f128, 12.0);
8241057 try comptime testCeilLegacy(f128, 12.0);
......@@ -835,8 +1068,8 @@ test "@trunc" {
8351068 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8361069 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8371070
838 try comptime testTrunc();
8391071 try testTrunc();
1072 try comptime testTrunc();
8401073}
8411074
8421075fn testTrunc() !void {
......@@ -854,14 +1087,14 @@ fn testTrunc() !void {
8541087
8551088test "@trunc with vectors" {
8561089 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
8591090 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8601091 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8611092 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();
8641096 try testTruncWithVectors();
1097 try comptime testTruncWithVectors();
8651098}
8661099
8671100fn testTruncWithVectors() !void {
......@@ -876,8 +1109,8 @@ fn testTruncWithVectors() !void {
8761109test "another, possibly redundant, @trunc test" {
8771110 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8781111 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
879 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8801112 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1113 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8811114
8821115 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
8831116 // https://github.com/ziglang/zig/issues/16846
......@@ -900,9 +1133,9 @@ test "another, possibly redundant, @trunc test" {
9001133test "@trunc f80" {
9011134 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9021135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
903 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9041136 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
9071140 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
9081141 // https://github.com/ziglang/zig/issues/12602
......@@ -922,9 +1155,9 @@ test "@trunc f80" {
9221155test "@trunc f128" {
9231156 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9241157 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
925 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9261158 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
9291162 try testTruncLegacy(f128, 12.0);
9301163 try comptime testTruncLegacy(f128, 12.0);
......@@ -945,11 +1178,11 @@ fn testTruncLegacy(comptime T: type, x: T) !void {
9451178}
9461179
9471180test "negation f16" {
948 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
9491181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9501182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9511183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9521184 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1185 if (no_x86_64_hardware_f16_support) return error.SkipZigTest;
9531186
9541187 if (builtin.os.tag == .freebsd) {
9551188 // TODO file issue to track this failure
......@@ -1011,11 +1244,11 @@ test "negation f64" {
10111244}
10121245
10131246test "negation f80" {
1014 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10151247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10161248 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10171249 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10181250 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1251 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10191252
10201253 const S = struct {
10211254 fn doTheTest() !void {
......@@ -1032,11 +1265,11 @@ test "negation f80" {
10321265}
10331266
10341267test "negation f128" {
1035 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10361268 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10371269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10381270 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10391271 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1272 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10401273
10411274 const S = struct {
10421275 fn doTheTest() !void {
......@@ -1075,11 +1308,11 @@ test "f128 at compile time is lossy" {
10751308}
10761309
10771310test "comptime fixed-width float zero divided by zero produces NaN" {
1078 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10791311 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10801312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10811313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10821314 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1315 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
10831316
10841317 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
10851318 try expect(math.isNan(@as(F, 0) / @as(F, 0)));
......@@ -1182,11 +1415,11 @@ test "nan negation f128" {
11821415}
11831416
11841417test "nan negation f80" {
1185 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11861418 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11871419 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11881420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11891421 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1422 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
11901423
11911424 const nan_comptime = comptime math.nan(f80);
11921425 const neg_nan_comptime = -nan_comptime;
test/behavior/math.zig+18-9
......@@ -7,6 +7,8 @@ const maxInt = std.math.maxInt;
77const minInt = std.math.minInt;
88const mem = std.mem;
99const 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
1113test "assignment operators" {
1214 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 {
14371439 try expect(@abs(@mod(@as(T, a), @as(T, b)) - @as(T, c)) < epsilon);
14381440}
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" {
14411455 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14421456 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1443 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
14441457 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14451458 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
14471461 try testRound(f64, 12.0);
14481462 try comptime testRound(f64, 12.0);
14491463 try testRound(f32, 12.0);
14501464 try comptime testRound(f32, 12.0);
1451 try testRound(f16, 12.0);
1452 try comptime testRound(f16, 12.0);
14531465
14541466 const x = 14.0;
14551467 const y = x + 0.4;
......@@ -1464,6 +1476,7 @@ test "@round f80" {
14641476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14651477 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14661478 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
14681481 try testRound(f80, 12.0);
14691482 try comptime testRound(f80, 12.0);
......@@ -1476,6 +1489,7 @@ test "@round f128" {
14761489 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14771490 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
14781491 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
14801494 try testRound(f128, 12.0);
14811495 try comptime testRound(f128, 12.0);
......@@ -1608,11 +1622,6 @@ test "signed zeros are represented properly" {
16081622 try comptime S.doTheTest();
16091623}
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
16161625test "absFloat" {
16171626 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16181627 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO