| author | |
| committer | |
| log | fbe5bf469e17ffd57b34762fd0206587f5758a52 |
| tree | e657e3c79c1e9ea76daa7d388bdd55340ebc6d7d |
| parent | 1eb023908d50e601f68f2200c3cf126ca3035167 |
3 files changed, 301 insertions(+), 187 deletions(-)
src/arch/x86_64/CodeGen.zig+205-173| ... | @@ -6570,6 +6570,34 @@ fn genBinOp( | ... | @@ -6570,6 +6570,34 @@ fn genBinOp( |
| 6570 | const lhs_ty = self.typeOf(lhs_air); | 6570 | const lhs_ty = self.typeOf(lhs_air); |
| 6571 | const rhs_ty = self.typeOf(rhs_air); | 6571 | const rhs_ty = self.typeOf(rhs_air); |
| 6572 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); | 6572 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); |
| 6573 | |||
| 6574 | if (lhs_ty.isRuntimeFloat() and switch (lhs_ty.floatBits(self.target.*)) { | ||
| 6575 | 16 => !self.hasFeature(.f16c), | ||
| 6576 | 32, 64 => false, | ||
| 6577 | 80, 128 => true, | ||
| 6578 | else => unreachable, | ||
| 6579 | }) { | ||
| 6580 | var callee: ["__add?f3".len]u8 = undefined; | ||
| 6581 | return self.genCall(.{ .lib = .{ | ||
| 6582 | .return_type = lhs_ty.toIntern(), | ||
| 6583 | .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() }, | ||
| 6584 | .callee = switch (air_tag) { | ||
| 6585 | .add, .sub, .mul, .div_float => std.fmt.bufPrint(&callee, "__{s}{c}f3", .{ | ||
| 6586 | @tagName(air_tag)[0..3], | ||
| 6587 | floatCompilerRtAbiName(lhs_ty.floatBits(self.target.*)), | ||
| 6588 | }), | ||
| 6589 | .min, .max => std.fmt.bufPrint(&callee, "{s}f{s}{s}", .{ | ||
| 6590 | floatLibcAbiPrefix(lhs_ty), | ||
| 6591 | @tagName(air_tag), | ||
| 6592 | floatLibcAbiSuffix(lhs_ty), | ||
| 6593 | }), | ||
| 6594 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ | ||
| 6595 | @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?), | ||
| 6596 | }), | ||
| 6597 | } catch unreachable, | ||
| 6598 | } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }); | ||
| 6599 | } | ||
| 6600 | |||
| 6573 | if ((lhs_ty.scalarType(mod).isRuntimeFloat() and | 6601 | if ((lhs_ty.scalarType(mod).isRuntimeFloat() and |
| 6574 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or | 6602 | lhs_ty.scalarType(mod).floatBits(self.target.*) == 80) or |
| 6575 | lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)) | 6603 | lhs_ty.abiSize(mod) > @as(u6, if (self.hasFeature(.avx)) 32 else 16)) |
| ... | @@ -6830,7 +6858,8 @@ fn genBinOp( | ... | @@ -6830,7 +6858,8 @@ fn genBinOp( |
| 6830 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { | 6858 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) { |
| 6831 | else => unreachable, | 6859 | else => unreachable, |
| 6832 | .Float => switch (lhs_ty.floatBits(self.target.*)) { | 6860 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 6833 | 16 => if (self.hasFeature(.f16c)) { | 6861 | 16 => { |
| 6862 | assert(self.hasFeature(.f16c)); | ||
| 6834 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 6863 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 6835 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 6864 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 6836 | defer self.register_manager.unlockReg(tmp_lock); | 6865 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -6873,7 +6902,7 @@ fn genBinOp( | ... | @@ -6873,7 +6902,7 @@ fn genBinOp( |
| 6873 | Immediate.u(0b1_00), | 6902 | Immediate.u(0b1_00), |
| 6874 | ); | 6903 | ); |
| 6875 | return dst_mcv; | 6904 | return dst_mcv; |
| 6876 | } else null, | 6905 | }, |
| 6877 | 32 => switch (air_tag) { | 6906 | 32 => switch (air_tag) { |
| 6878 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, | 6907 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, |
| 6879 | .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, | 6908 | .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, |
| ... | @@ -7134,181 +7163,184 @@ fn genBinOp( | ... | @@ -7134,181 +7163,184 @@ fn genBinOp( |
| 7134 | else => null, | 7163 | else => null, |
| 7135 | }, | 7164 | }, |
| 7136 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { | 7165 | .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { |
| 7137 | 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen(mod)) { | 7166 | 16 => tag: { |
| 7138 | 1 => { | 7167 | assert(self.hasFeature(.f16c)); |
| 7139 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 7168 | switch (lhs_ty.vectorLen(mod)) { |
| 7140 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7169 | 1 => { |
| 7141 | defer self.register_manager.unlockReg(tmp_lock); | 7170 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 7171 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 7172 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 7142 | 7173 | ||
| 7143 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( | 7174 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( |
| 7144 | .{ .vp_w, .insr }, | 7175 | .{ .vp_w, .insr }, |
| 7145 | dst_reg, | 7176 | dst_reg, |
| 7146 | dst_reg, | 7177 | dst_reg, |
| 7147 | src_mcv.mem(.word), | 7178 | src_mcv.mem(.word), |
| 7148 | Immediate.u(1), | 7179 | Immediate.u(1), |
| 7149 | ) else try self.asmRegisterRegisterRegister( | 7180 | ) else try self.asmRegisterRegisterRegister( |
| 7150 | .{ .vp_, .unpcklwd }, | 7181 | .{ .vp_, .unpcklwd }, |
| 7151 | dst_reg, | 7182 | dst_reg, |
| 7152 | dst_reg, | 7183 | dst_reg, |
| 7153 | (if (src_mcv.isRegister()) | 7184 | (if (src_mcv.isRegister()) |
| 7154 | src_mcv.getReg().? | 7185 | src_mcv.getReg().? |
| 7155 | else | 7186 | else |
| 7156 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7187 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7157 | ); | 7188 | ); |
| 7158 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); | 7189 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 7159 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); | 7190 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); |
| 7160 | try self.asmRegisterRegisterRegister( | 7191 | try self.asmRegisterRegisterRegister( |
| 7161 | switch (air_tag) { | 7192 | switch (air_tag) { |
| 7162 | .add => .{ .v_ss, .add }, | 7193 | .add => .{ .v_ss, .add }, |
| 7163 | .sub => .{ .v_ss, .sub }, | 7194 | .sub => .{ .v_ss, .sub }, |
| 7164 | .mul => .{ .v_ss, .mul }, | 7195 | .mul => .{ .v_ss, .mul }, |
| 7165 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, | 7196 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, |
| 7166 | .max => .{ .v_ss, .max }, | 7197 | .max => .{ .v_ss, .max }, |
| 7167 | .min => .{ .v_ss, .max }, | 7198 | .min => .{ .v_ss, .max }, |
| 7168 | else => unreachable, | 7199 | else => unreachable, |
| 7169 | }, | 7200 | }, |
| 7170 | dst_reg, | 7201 | dst_reg, |
| 7171 | dst_reg, | 7202 | dst_reg, |
| 7172 | tmp_reg, | 7203 | tmp_reg, |
| 7173 | ); | 7204 | ); |
| 7174 | try self.asmRegisterRegisterImmediate( | 7205 | try self.asmRegisterRegisterImmediate( |
| 7175 | .{ .v_, .cvtps2ph }, | 7206 | .{ .v_, .cvtps2ph }, |
| 7176 | dst_reg, | 7207 | dst_reg, |
| 7177 | dst_reg, | 7208 | dst_reg, |
| 7178 | Immediate.u(0b1_00), | 7209 | Immediate.u(0b1_00), |
| 7179 | ); | 7210 | ); |
| 7180 | return dst_mcv; | 7211 | return dst_mcv; |
| 7181 | }, | 7212 | }, |
| 7182 | 2 => { | 7213 | 2 => { |
| 7183 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 7214 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 7184 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7215 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7185 | defer self.register_manager.unlockReg(tmp_lock); | 7216 | defer self.register_manager.unlockReg(tmp_lock); |
| 7186 | 7217 | ||
| 7187 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | 7218 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( |
| 7188 | .{ .vp_d, .insr }, | 7219 | .{ .vp_d, .insr }, |
| 7189 | dst_reg, | 7220 | dst_reg, |
| 7190 | src_mcv.mem(.dword), | 7221 | src_mcv.mem(.dword), |
| 7191 | Immediate.u(1), | 7222 | Immediate.u(1), |
| 7192 | ) else try self.asmRegisterRegisterRegister( | 7223 | ) else try self.asmRegisterRegisterRegister( |
| 7193 | .{ .v_ps, .unpckl }, | 7224 | .{ .v_ps, .unpckl }, |
| 7194 | dst_reg, | 7225 | dst_reg, |
| 7195 | dst_reg, | 7226 | dst_reg, |
| 7196 | (if (src_mcv.isRegister()) | 7227 | (if (src_mcv.isRegister()) |
| 7197 | src_mcv.getReg().? | 7228 | src_mcv.getReg().? |
| 7198 | else | 7229 | else |
| 7199 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7230 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7200 | ); | 7231 | ); |
| 7201 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); | 7232 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 7202 | try self.asmRegisterRegisterRegister( | 7233 | try self.asmRegisterRegisterRegister( |
| 7203 | .{ .v_ps, .movhl }, | 7234 | .{ .v_ps, .movhl }, |
| 7204 | tmp_reg, | 7235 | tmp_reg, |
| 7205 | dst_reg, | 7236 | dst_reg, |
| 7206 | dst_reg, | 7237 | dst_reg, |
| 7207 | ); | 7238 | ); |
| 7208 | try self.asmRegisterRegisterRegister( | 7239 | try self.asmRegisterRegisterRegister( |
| 7209 | switch (air_tag) { | 7240 | switch (air_tag) { |
| 7210 | .add => .{ .v_ps, .add }, | 7241 | .add => .{ .v_ps, .add }, |
| 7211 | .sub => .{ .v_ps, .sub }, | 7242 | .sub => .{ .v_ps, .sub }, |
| 7212 | .mul => .{ .v_ps, .mul }, | 7243 | .mul => .{ .v_ps, .mul }, |
| 7213 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 7244 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 7214 | .max => .{ .v_ps, .max }, | 7245 | .max => .{ .v_ps, .max }, |
| 7215 | .min => .{ .v_ps, .max }, | 7246 | .min => .{ .v_ps, .max }, |
| 7216 | else => unreachable, | 7247 | else => unreachable, |
| 7217 | }, | 7248 | }, |
| 7218 | dst_reg, | 7249 | dst_reg, |
| 7219 | dst_reg, | 7250 | dst_reg, |
| 7220 | tmp_reg, | 7251 | tmp_reg, |
| 7221 | ); | 7252 | ); |
| 7222 | try self.asmRegisterRegisterImmediate( | 7253 | try self.asmRegisterRegisterImmediate( |
| 7223 | .{ .v_, .cvtps2ph }, | 7254 | .{ .v_, .cvtps2ph }, |
| 7224 | dst_reg, | 7255 | dst_reg, |
| 7225 | dst_reg, | 7256 | dst_reg, |
| 7226 | Immediate.u(0b1_00), | 7257 | Immediate.u(0b1_00), |
| 7227 | ); | 7258 | ); |
| 7228 | return dst_mcv; | 7259 | return dst_mcv; |
| 7229 | }, | 7260 | }, |
| 7230 | 3...4 => { | 7261 | 3...4 => { |
| 7231 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | 7262 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); |
| 7232 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7263 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7233 | defer self.register_manager.unlockReg(tmp_lock); | 7264 | defer self.register_manager.unlockReg(tmp_lock); |
| 7234 | 7265 | ||
| 7235 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); | 7266 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 7236 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 7267 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7237 | .{ .v_ps, .cvtph2 }, | 7268 | .{ .v_ps, .cvtph2 }, |
| 7238 | tmp_reg, | 7269 | tmp_reg, |
| 7239 | src_mcv.mem(.qword), | 7270 | src_mcv.mem(.qword), |
| 7240 | ) else try self.asmRegisterRegister( | 7271 | ) else try self.asmRegisterRegister( |
| 7241 | .{ .v_ps, .cvtph2 }, | 7272 | .{ .v_ps, .cvtph2 }, |
| 7242 | tmp_reg, | 7273 | tmp_reg, |
| 7243 | (if (src_mcv.isRegister()) | 7274 | (if (src_mcv.isRegister()) |
| 7244 | src_mcv.getReg().? | 7275 | src_mcv.getReg().? |
| 7245 | else | 7276 | else |
| 7246 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7277 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7247 | ); | 7278 | ); |
| 7248 | try self.asmRegisterRegisterRegister( | 7279 | try self.asmRegisterRegisterRegister( |
| 7249 | switch (air_tag) { | 7280 | switch (air_tag) { |
| 7250 | .add => .{ .v_ps, .add }, | 7281 | .add => .{ .v_ps, .add }, |
| 7251 | .sub => .{ .v_ps, .sub }, | 7282 | .sub => .{ .v_ps, .sub }, |
| 7252 | .mul => .{ .v_ps, .mul }, | 7283 | .mul => .{ .v_ps, .mul }, |
| 7253 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 7284 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 7254 | .max => .{ .v_ps, .max }, | 7285 | .max => .{ .v_ps, .max }, |
| 7255 | .min => .{ .v_ps, .max }, | 7286 | .min => .{ .v_ps, .max }, |
| 7256 | else => unreachable, | 7287 | else => unreachable, |
| 7257 | }, | 7288 | }, |
| 7258 | dst_reg, | 7289 | dst_reg, |
| 7259 | dst_reg, | 7290 | dst_reg, |
| 7260 | tmp_reg, | 7291 | tmp_reg, |
| 7261 | ); | 7292 | ); |
| 7262 | try self.asmRegisterRegisterImmediate( | 7293 | try self.asmRegisterRegisterImmediate( |
| 7263 | .{ .v_, .cvtps2ph }, | 7294 | .{ .v_, .cvtps2ph }, |
| 7264 | dst_reg, | 7295 | dst_reg, |
| 7265 | dst_reg, | 7296 | dst_reg, |
| 7266 | Immediate.u(0b1_00), | 7297 | Immediate.u(0b1_00), |
| 7267 | ); | 7298 | ); |
| 7268 | return dst_mcv; | 7299 | return dst_mcv; |
| 7269 | }, | 7300 | }, |
| 7270 | 5...8 => { | 7301 | 5...8 => { |
| 7271 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); | 7302 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); |
| 7272 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7303 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7273 | defer self.register_manager.unlockReg(tmp_lock); | 7304 | defer self.register_manager.unlockReg(tmp_lock); |
| 7274 | 7305 | ||
| 7275 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); | 7306 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); |
| 7276 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 7307 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 7277 | .{ .v_ps, .cvtph2 }, | 7308 | .{ .v_ps, .cvtph2 }, |
| 7278 | tmp_reg, | 7309 | tmp_reg, |
| 7279 | src_mcv.mem(.xword), | 7310 | src_mcv.mem(.xword), |
| 7280 | ) else try self.asmRegisterRegister( | 7311 | ) else try self.asmRegisterRegister( |
| 7281 | .{ .v_ps, .cvtph2 }, | 7312 | .{ .v_ps, .cvtph2 }, |
| 7282 | tmp_reg, | 7313 | tmp_reg, |
| 7283 | (if (src_mcv.isRegister()) | 7314 | (if (src_mcv.isRegister()) |
| 7284 | src_mcv.getReg().? | 7315 | src_mcv.getReg().? |
| 7285 | else | 7316 | else |
| 7286 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 7317 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 7287 | ); | 7318 | ); |
| 7288 | try self.asmRegisterRegisterRegister( | 7319 | try self.asmRegisterRegisterRegister( |
| 7289 | switch (air_tag) { | 7320 | switch (air_tag) { |
| 7290 | .add => .{ .v_ps, .add }, | 7321 | .add => .{ .v_ps, .add }, |
| 7291 | .sub => .{ .v_ps, .sub }, | 7322 | .sub => .{ .v_ps, .sub }, |
| 7292 | .mul => .{ .v_ps, .mul }, | 7323 | .mul => .{ .v_ps, .mul }, |
| 7293 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 7324 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 7294 | .max => .{ .v_ps, .max }, | 7325 | .max => .{ .v_ps, .max }, |
| 7295 | .min => .{ .v_ps, .max }, | 7326 | .min => .{ .v_ps, .max }, |
| 7296 | else => unreachable, | 7327 | else => unreachable, |
| 7297 | }, | 7328 | }, |
| 7298 | dst_reg.to256(), | 7329 | dst_reg.to256(), |
| 7299 | dst_reg.to256(), | 7330 | dst_reg.to256(), |
| 7300 | tmp_reg, | 7331 | tmp_reg, |
| 7301 | ); | 7332 | ); |
| 7302 | try self.asmRegisterRegisterImmediate( | 7333 | try self.asmRegisterRegisterImmediate( |
| 7303 | .{ .v_, .cvtps2ph }, | 7334 | .{ .v_, .cvtps2ph }, |
| 7304 | dst_reg, | 7335 | dst_reg, |
| 7305 | dst_reg.to256(), | 7336 | dst_reg.to256(), |
| 7306 | Immediate.u(0b1_00), | 7337 | Immediate.u(0b1_00), |
| 7307 | ); | 7338 | ); |
| 7308 | return dst_mcv; | 7339 | return dst_mcv; |
| 7309 | }, | 7340 | }, |
| 7310 | else => null, | 7341 | else => break :tag null, |
| 7311 | } else null, | 7342 | } |
| 7343 | }, | ||
| 7312 | 32 => switch (lhs_ty.vectorLen(mod)) { | 7344 | 32 => switch (lhs_ty.vectorLen(mod)) { |
| 7313 | 1 => switch (air_tag) { | 7345 | 1 => switch (air_tag) { |
| 7314 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, | 7346 | .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, |
test/behavior/floatop.zig+96-11| ... | @@ -19,6 +19,99 @@ fn epsForType(comptime T: type) T { | ... | @@ -19,6 +19,99 @@ fn epsForType(comptime T: type) T { |
| 19 | }; | 19 | }; |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | test "add f16" { | ||
| 23 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 24 | |||
| 25 | try testAdd(f16); | ||
| 26 | try comptime testAdd(f16); | ||
| 27 | } | ||
| 28 | |||
| 29 | test "add f32/f64" { | ||
| 30 | try testAdd(f32); | ||
| 31 | try comptime testAdd(f32); | ||
| 32 | try testAdd(f64); | ||
| 33 | try comptime testAdd(f64); | ||
| 34 | } | ||
| 35 | |||
| 36 | test "add f80/f128/c_longdouble" { | ||
| 37 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 38 | |||
| 39 | try testAdd(f80); | ||
| 40 | try comptime testAdd(f80); | ||
| 41 | try testAdd(f128); | ||
| 42 | try comptime testAdd(f128); | ||
| 43 | try testAdd(c_longdouble); | ||
| 44 | try comptime testAdd(c_longdouble); | ||
| 45 | } | ||
| 46 | |||
| 47 | fn testAdd(comptime T: type) !void { | ||
| 48 | var one_point_two_five: T = 1.25; | ||
| 49 | var two_point_seven_five: T = 2.75; | ||
| 50 | try expect(one_point_two_five + two_point_seven_five == 4); | ||
| 51 | } | ||
| 52 | |||
| 53 | test "sub f16" { | ||
| 54 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 55 | |||
| 56 | try testSub(f16); | ||
| 57 | try comptime testSub(f16); | ||
| 58 | } | ||
| 59 | |||
| 60 | test "sub f32/f64" { | ||
| 61 | try testSub(f32); | ||
| 62 | try comptime testSub(f32); | ||
| 63 | try testSub(f64); | ||
| 64 | try comptime testSub(f64); | ||
| 65 | } | ||
| 66 | |||
| 67 | test "sub f80/f128/c_longdouble" { | ||
| 68 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 69 | |||
| 70 | try testSub(f80); | ||
| 71 | try comptime testSub(f80); | ||
| 72 | try testSub(f128); | ||
| 73 | try comptime testSub(f128); | ||
| 74 | try testSub(c_longdouble); | ||
| 75 | try comptime testSub(c_longdouble); | ||
| 76 | } | ||
| 77 | |||
| 78 | fn testSub(comptime T: type) !void { | ||
| 79 | var one_point_two_five: T = 1.25; | ||
| 80 | var two_point_seven_five: T = 2.75; | ||
| 81 | try expect(one_point_two_five - two_point_seven_five == -1.5); | ||
| 82 | } | ||
| 83 | |||
| 84 | test "mul f16" { | ||
| 85 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | ||
| 86 | |||
| 87 | try testMul(f16); | ||
| 88 | try comptime testMul(f16); | ||
| 89 | } | ||
| 90 | |||
| 91 | test "mul f32/f64" { | ||
| 92 | try testMul(f32); | ||
| 93 | try comptime testMul(f32); | ||
| 94 | try testMul(f64); | ||
| 95 | try comptime testMul(f64); | ||
| 96 | } | ||
| 97 | |||
| 98 | test "mul f80/f128/c_longdouble" { | ||
| 99 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 100 | |||
| 101 | try testMul(f80); | ||
| 102 | try comptime testMul(f80); | ||
| 103 | try testMul(f128); | ||
| 104 | try comptime testMul(f128); | ||
| 105 | try testMul(c_longdouble); | ||
| 106 | try comptime testMul(c_longdouble); | ||
| 107 | } | ||
| 108 | |||
| 109 | fn testMul(comptime T: type) !void { | ||
| 110 | var one_point_two_five: T = 1.25; | ||
| 111 | var two_point_seven_five: T = 2.75; | ||
| 112 | try expect(one_point_two_five * two_point_seven_five == 3.4375); | ||
| 113 | } | ||
| 114 | |||
| 22 | test "cmp f16" { | 115 | test "cmp f16" { |
| 23 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 116 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 117 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| ... | @@ -216,7 +309,7 @@ test "more @sqrt f16 tests" { | ... | @@ -216,7 +309,7 @@ test "more @sqrt f16 tests" { |
| 216 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 309 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 217 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 310 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 218 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 311 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 219 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | 312 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 220 | 313 | ||
| 221 | // TODO these are not all passing at comptime | 314 | // TODO these are not all passing at comptime |
| 222 | try expect(@sqrt(@as(f16, 0.0)) == 0.0); | 315 | try expect(@sqrt(@as(f16, 0.0)) == 0.0); |
| ... | @@ -269,7 +362,6 @@ test "@sin f16" { | ... | @@ -269,7 +362,6 @@ test "@sin f16" { |
| 269 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 362 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 270 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 363 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 271 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 364 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 272 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 273 | 365 | ||
| 274 | try testSin(f16); | 366 | try testSin(f16); |
| 275 | try comptime testSin(f16); | 367 | try comptime testSin(f16); |
| ... | @@ -339,7 +431,6 @@ test "@cos f16" { | ... | @@ -339,7 +431,6 @@ test "@cos f16" { |
| 339 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 431 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 340 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 432 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 341 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 433 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 342 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 343 | 434 | ||
| 344 | try testCos(f16); | 435 | try testCos(f16); |
| 345 | try comptime testCos(f16); | 436 | try comptime testCos(f16); |
| ... | @@ -409,7 +500,6 @@ test "@tan f16" { | ... | @@ -409,7 +500,6 @@ test "@tan f16" { |
| 409 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 500 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 410 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 501 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 411 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 502 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 412 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 413 | 503 | ||
| 414 | try testTan(f16); | 504 | try testTan(f16); |
| 415 | try comptime testTan(f16); | 505 | try comptime testTan(f16); |
| ... | @@ -479,7 +569,6 @@ test "@exp f16" { | ... | @@ -479,7 +569,6 @@ test "@exp f16" { |
| 479 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 569 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 480 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 570 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 481 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 571 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 482 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 483 | 572 | ||
| 484 | try testExp(f16); | 573 | try testExp(f16); |
| 485 | try comptime testExp(f16); | 574 | try comptime testExp(f16); |
| ... | @@ -549,7 +638,6 @@ test "@exp2 f16" { | ... | @@ -549,7 +638,6 @@ test "@exp2 f16" { |
| 549 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 638 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 550 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 639 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 551 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 640 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 552 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 553 | 641 | ||
| 554 | try testExp2(f16); | 642 | try testExp2(f16); |
| 555 | try comptime testExp2(f16); | 643 | try comptime testExp2(f16); |
| ... | @@ -619,7 +707,6 @@ test "@log f16" { | ... | @@ -619,7 +707,6 @@ test "@log f16" { |
| 619 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 707 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 620 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 708 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 621 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 709 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 622 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 623 | 710 | ||
| 624 | try testLog(f16); | 711 | try testLog(f16); |
| 625 | try comptime testLog(f16); | 712 | try comptime testLog(f16); |
| ... | @@ -687,7 +774,6 @@ test "@log2 f16" { | ... | @@ -687,7 +774,6 @@ test "@log2 f16" { |
| 687 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 774 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 688 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 775 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 689 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 776 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 690 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 691 | 777 | ||
| 692 | try testLog2(f16); | 778 | try testLog2(f16); |
| 693 | try comptime testLog2(f16); | 779 | try comptime testLog2(f16); |
| ... | @@ -761,7 +847,6 @@ test "@log10 f16" { | ... | @@ -761,7 +847,6 @@ test "@log10 f16" { |
| 761 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 847 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 762 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 848 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 763 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 849 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 764 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | ||
| 765 | 850 | ||
| 766 | try testLog10(f16); | 851 | try testLog10(f16); |
| 767 | try comptime testLog10(f16); | 852 | try comptime testLog10(f16); |
| ... | @@ -829,7 +914,7 @@ test "@abs f16" { | ... | @@ -829,7 +914,7 @@ test "@abs f16" { |
| 829 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 914 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 830 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 915 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 831 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 916 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 832 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | 917 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 833 | 918 | ||
| 834 | try testFabs(f16); | 919 | try testFabs(f16); |
| 835 | try comptime testFabs(f16); | 920 | try comptime testFabs(f16); |
| ... | @@ -1186,7 +1271,7 @@ test "neg f16" { | ... | @@ -1186,7 +1271,7 @@ test "neg f16" { |
| 1186 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1271 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1187 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1272 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1188 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 1273 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 1189 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; | 1274 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 1190 | 1275 | ||
| 1191 | if (builtin.os.tag == .freebsd) { | 1276 | if (builtin.os.tag == .freebsd) { |
| 1192 | // TODO file issue to track this failure | 1277 | // TODO file issue to track this failure |
test/behavior/math.zig-3| ... | @@ -7,8 +7,6 @@ const maxInt = std.math.maxInt; | ... | @@ -7,8 +7,6 @@ const maxInt = std.math.maxInt; |
| 7 | const minInt = std.math.minInt; | 7 | const minInt = std.math.minInt; |
| 8 | const mem = std.mem; | 8 | const mem = std.mem; |
| 9 | const math = std.math; | 9 | const math = std.math; |
| 10 | const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and | ||
| 11 | !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c); | ||
| 12 | 10 | ||
| 13 | test "assignment operators" { | 11 | test "assignment operators" { |
| 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 12 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1444,7 +1442,6 @@ test "@round f16" { | ... | @@ -1444,7 +1442,6 @@ test "@round f16" { |
| 1444 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1442 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1445 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1443 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1446 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; | 1444 | if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest; |
| 1447 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO | ||
| 1448 | 1445 | ||
| 1449 | try testRound(f16, 12.0); | 1446 | try testRound(f16, 12.0); |
| 1450 | try comptime testRound(f16, 12.0); | 1447 | try comptime testRound(f16, 12.0); |