authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-07 20:42:46-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-08 07:36:20-04:00
log6778da4516e68c271cb50fe9c252ab4084daf16b
tree46e3bb0082569ecb678039e36fa2a422ae02a994
parentf8708e2c4d93eece5b3e131fd2d1b5b210806cd6

x86_64: implement binary operations for `f16` and `f16` vectors


7 files changed, 354 insertions(+), 46 deletions(-)

src/arch/x86_64/CodeGen.zig+240-21
...@@ -4497,14 +4497,15 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -4497,14 +4497,15 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4497 const tag = self.air.instructions.items(.tag)[inst];4497 const tag = self.air.instructions.items(.tag)[inst];
4498 try self.genBinOpMir(switch (ty_bits) {4498 try self.genBinOpMir(switch (ty_bits) {
4499 // No point using an extra prefix byte for *pd which performs the same operation.4499 // No point using an extra prefix byte for *pd which performs the same operation.
4500 32, 64 => switch (tag) {4500 16, 32, 64, 128 => switch (tag) {
4501 .neg => .xorps,4501 .neg => .xorps,
4502 .fabs => .andnps,4502 .fabs => .andnps,
4503 else => unreachable,4503 else => unreachable,
4504 },4504 },
4505 else => return self.fail("TODO implement airFloatSign for {}", .{4505 80 => return self.fail("TODO implement airFloatSign for {}", .{
4506 ty.fmt(self.bin_file.options.module.?),4506 ty.fmt(self.bin_file.options.module.?),
4507 }),4507 }),
4508 else => unreachable,
4508 }, vec_ty, dst_mcv, sign_mcv);4509 }, vec_ty, dst_mcv, sign_mcv);
4509 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });4510 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
4510}4511}
...@@ -6112,9 +6113,53 @@ fn genBinOp(...@@ -6112,9 +6113,53 @@ fn genBinOp(
6112 return dst_mcv;6113 return dst_mcv;
6113 }6114 }
61146115
6116 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);
6115 const mir_tag = if (@as(?Mir.Inst.Tag, switch (lhs_ty.zigTypeTag()) {6117 const mir_tag = if (@as(?Mir.Inst.Tag, switch (lhs_ty.zigTypeTag()) {
6116 else => unreachable,6118 else => unreachable,
6117 .Float => switch (lhs_ty.floatBits(self.target.*)) {6119 .Float => switch (lhs_ty.floatBits(self.target.*)) {
6120 16 => if (self.hasFeature(.f16c)) {
6121 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
6122 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6123 defer self.register_manager.unlockReg(tmp_lock);
6124
6125 if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
6126 .vpinsrw,
6127 dst_reg,
6128 dst_reg,
6129 src_mcv.mem(.word),
6130 Immediate.u(1),
6131 ) else try self.asmRegisterRegisterRegister(
6132 .vpunpcklwd,
6133 dst_reg,
6134 dst_reg,
6135 (if (src_mcv.isRegister())
6136 src_mcv.getReg().?
6137 else
6138 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
6139 );
6140 try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg);
6141 try self.asmRegisterRegister(.vmovshdup, tmp_reg, dst_reg);
6142 try self.asmRegisterRegisterRegister(
6143 switch (air_tag) {
6144 .add => .vaddss,
6145 .sub => .vsubss,
6146 .div_float, .div_trunc, .div_floor, .div_exact => .vdivss,
6147 .max => .vmaxss,
6148 .min => .vmaxss,
6149 else => unreachable,
6150 },
6151 dst_reg,
6152 dst_reg,
6153 tmp_reg,
6154 );
6155 try self.asmRegisterRegisterImmediate(
6156 .vcvtps2ph,
6157 dst_reg,
6158 dst_reg,
6159 Immediate.u(0b1_00),
6160 );
6161 return dst_mcv;
6162 } else null,
6118 32 => switch (air_tag) {6163 32 => switch (air_tag) {
6119 .add => if (self.hasFeature(.avx)) .vaddss else .addss,6164 .add => if (self.hasFeature(.avx)) .vaddss else .addss,
6120 .sub => if (self.hasFeature(.avx)) .vsubss else .subss,6165 .sub => if (self.hasFeature(.avx)) .vsubss else .subss,
...@@ -6141,12 +6186,178 @@ fn genBinOp(...@@ -6141,12 +6186,178 @@ fn genBinOp(
6141 .min => if (self.hasFeature(.avx)) .vminsd else .minsd,6186 .min => if (self.hasFeature(.avx)) .vminsd else .minsd,
6142 else => unreachable,6187 else => unreachable,
6143 },6188 },
6144 16, 80, 128 => null,6189 80, 128 => null,
6145 else => unreachable,6190 else => unreachable,
6146 },6191 },
6147 .Vector => switch (lhs_ty.childType().zigTypeTag()) {6192 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
6148 else => null,6193 else => null,
6149 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {6194 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
6195 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen()) {
6196 1 => {
6197 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
6198 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6199 defer self.register_manager.unlockReg(tmp_lock);
6200
6201 if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
6202 .vpinsrw,
6203 dst_reg,
6204 dst_reg,
6205 src_mcv.mem(.word),
6206 Immediate.u(1),
6207 ) else try self.asmRegisterRegisterRegister(
6208 .vpunpcklwd,
6209 dst_reg,
6210 dst_reg,
6211 (if (src_mcv.isRegister())
6212 src_mcv.getReg().?
6213 else
6214 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
6215 );
6216 try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg);
6217 try self.asmRegisterRegister(.vmovshdup, tmp_reg, dst_reg);
6218 try self.asmRegisterRegisterRegister(
6219 switch (air_tag) {
6220 .add => .vaddss,
6221 .sub => .vsubss,
6222 .div_float, .div_trunc, .div_floor, .div_exact => .vdivss,
6223 .max => .vmaxss,
6224 .min => .vmaxss,
6225 else => unreachable,
6226 },
6227 dst_reg,
6228 dst_reg,
6229 tmp_reg,
6230 );
6231 try self.asmRegisterRegisterImmediate(
6232 .vcvtps2ph,
6233 dst_reg,
6234 dst_reg,
6235 Immediate.u(0b1_00),
6236 );
6237 return dst_mcv;
6238 },
6239 2 => {
6240 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
6241 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6242 defer self.register_manager.unlockReg(tmp_lock);
6243
6244 if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate(
6245 .vpinsrd,
6246 dst_reg,
6247 src_mcv.mem(.dword),
6248 Immediate.u(1),
6249 ) else try self.asmRegisterRegisterRegister(
6250 .vunpcklps,
6251 dst_reg,
6252 dst_reg,
6253 (if (src_mcv.isRegister())
6254 src_mcv.getReg().?
6255 else
6256 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
6257 );
6258 try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg);
6259 try self.asmRegisterRegisterRegister(.vmovhlps, tmp_reg, dst_reg, dst_reg);
6260 try self.asmRegisterRegisterRegister(
6261 switch (air_tag) {
6262 .add => .vaddps,
6263 .sub => .vsubps,
6264 .div_float, .div_trunc, .div_floor, .div_exact => .vdivps,
6265 .max => .vmaxps,
6266 .min => .vmaxps,
6267 else => unreachable,
6268 },
6269 dst_reg,
6270 dst_reg,
6271 tmp_reg,
6272 );
6273 try self.asmRegisterRegisterImmediate(
6274 .vcvtps2ph,
6275 dst_reg,
6276 dst_reg,
6277 Immediate.u(0b1_00),
6278 );
6279 return dst_mcv;
6280 },
6281 3...4 => {
6282 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128();
6283 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6284 defer self.register_manager.unlockReg(tmp_lock);
6285
6286 try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg);
6287 if (src_mcv.isMemory()) try self.asmRegisterMemory(
6288 .vcvtph2ps,
6289 tmp_reg,
6290 src_mcv.mem(.qword),
6291 ) else try self.asmRegisterRegister(
6292 .vcvtph2ps,
6293 tmp_reg,
6294 (if (src_mcv.isRegister())
6295 src_mcv.getReg().?
6296 else
6297 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
6298 );
6299 try self.asmRegisterRegisterRegister(
6300 switch (air_tag) {
6301 .add => .vaddps,
6302 .sub => .vsubps,
6303 .div_float, .div_trunc, .div_floor, .div_exact => .vdivps,
6304 .max => .vmaxps,
6305 .min => .vmaxps,
6306 else => unreachable,
6307 },
6308 dst_reg,
6309 dst_reg,
6310 tmp_reg,
6311 );
6312 try self.asmRegisterRegisterImmediate(
6313 .vcvtps2ph,
6314 dst_reg,
6315 dst_reg,
6316 Immediate.u(0b1_00),
6317 );
6318 return dst_mcv;
6319 },
6320 5...8 => {
6321 const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256();
6322 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6323 defer self.register_manager.unlockReg(tmp_lock);
6324
6325 try self.asmRegisterRegister(.vcvtph2ps, dst_reg.to256(), dst_reg);
6326 if (src_mcv.isMemory()) try self.asmRegisterMemory(
6327 .vcvtph2ps,
6328 tmp_reg,
6329 src_mcv.mem(.xword),
6330 ) else try self.asmRegisterRegister(
6331 .vcvtph2ps,
6332 tmp_reg,
6333 (if (src_mcv.isRegister())
6334 src_mcv.getReg().?
6335 else
6336 try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(),
6337 );
6338 try self.asmRegisterRegisterRegister(
6339 switch (air_tag) {
6340 .add => .vaddps,
6341 .sub => .vsubps,
6342 .div_float, .div_trunc, .div_floor, .div_exact => .vdivps,
6343 .max => .vmaxps,
6344 .min => .vmaxps,
6345 else => unreachable,
6346 },
6347 dst_reg.to256(),
6348 dst_reg.to256(),
6349 tmp_reg,
6350 );
6351 try self.asmRegisterRegisterImmediate(
6352 .vcvtps2ph,
6353 dst_reg,
6354 dst_reg.to256(),
6355 Immediate.u(0b1_00),
6356 );
6357 return dst_mcv;
6358 },
6359 else => null,
6360 } else null,
6150 32 => switch (lhs_ty.vectorLen()) {6361 32 => switch (lhs_ty.vectorLen()) {
6151 1 => switch (air_tag) {6362 1 => switch (air_tag) {
6152 .add => if (self.hasFeature(.avx)) .vaddss else .addss,6363 .add => if (self.hasFeature(.avx)) .vaddss else .addss,
...@@ -6223,14 +6434,13 @@ fn genBinOp(...@@ -6223,14 +6434,13 @@ fn genBinOp(
6223 } else null,6434 } else null,
6224 else => null,6435 else => null,
6225 },6436 },
6226 16, 80, 128 => null,6437 80, 128 => null,
6227 else => unreachable,6438 else => unreachable,
6228 },6439 },
6229 },6440 },
6230 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{6441 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
6231 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),6442 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6232 });6443 });
6233 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);
6234 if (self.hasFeature(.avx)) {6444 if (self.hasFeature(.avx)) {
6235 const src1_alias =6445 const src1_alias =
6236 if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size);6446 if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size);
...@@ -7139,21 +7349,21 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -7139,21 +7349,21 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
7139 const tmp2_lock = self.register_manager.lockRegAssumeUnused(tmp2_reg);7349 const tmp2_lock = self.register_manager.lockRegAssumeUnused(tmp2_reg);
7140 defer self.register_manager.unlockReg(tmp2_lock);7350 defer self.register_manager.unlockReg(tmp2_lock);
71417351
7142 if (src_mcv.isRegister())7352 if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
7143 try self.asmRegisterRegisterRegister(7353 .vpinsrw,
7144 .vpunpcklwd,7354 tmp1_reg,
7145 tmp1_reg,7355 dst_reg.to128(),
7146 dst_reg.to128(),7356 src_mcv.mem(.word),
7147 src_mcv.getReg().?.to128(),7357 Immediate.u(1),
7148 )7358 ) else try self.asmRegisterRegisterRegister(
7149 else7359 .vpunpcklwd,
7150 try self.asmRegisterRegisterMemoryImmediate(7360 tmp1_reg,
7151 .vpinsrw,7361 dst_reg.to128(),
7152 tmp1_reg,7362 (if (src_mcv.isRegister())
7153 dst_reg.to128(),7363 src_mcv.getReg().?
7154 src_mcv.mem(.word),7364 else
7155 Immediate.u(1),7365 try self.copyToTmpRegister(ty, src_mcv)).to128(),
7156 );7366 );
7157 try self.asmRegisterRegister(.vcvtph2ps, tmp1_reg, tmp1_reg);7367 try self.asmRegisterRegister(.vcvtph2ps, tmp1_reg, tmp1_reg);
7158 try self.asmRegisterRegister(.vmovshdup, tmp2_reg, tmp1_reg);7368 try self.asmRegisterRegister(.vmovshdup, tmp2_reg, tmp1_reg);
7159 try self.genBinOpMir(.ucomiss, ty, tmp1_mcv, tmp2_mcv);7369 try self.genBinOpMir(.ucomiss, ty, tmp1_mcv, tmp2_mcv);
...@@ -8139,7 +8349,16 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.Tag {...@@ -8139,7 +8349,16 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.Tag {
8139 },8349 },
8140 .Vector => switch (ty.childType().zigTypeTag()) {8350 .Vector => switch (ty.childType().zigTypeTag()) {
8141 .Float => switch (ty.childType().floatBits(self.target.*)) {8351 .Float => switch (ty.childType().floatBits(self.target.*)) {
8142 16 => unreachable, // needs special handling8352 16 => switch (ty.vectorLen()) {
8353 1 => unreachable, // needs special handling
8354 2 => return if (self.hasFeature(.avx)) .vmovss else .movss,
8355 3...4 => return if (self.hasFeature(.avx)) .vmovsd else .movsd,
8356 5...8 => return if (self.hasFeature(.avx))
8357 if (aligned) .vmovaps else .vmovups
8358 else if (aligned) .movaps else .movups,
8359 9...16 => if (self.hasFeature(.avx)) return if (aligned) .vmovaps else .vmovups,
8360 else => {},
8361 },
8143 32 => switch (ty.vectorLen()) {8362 32 => switch (ty.vectorLen()) {
8144 1 => return if (self.hasFeature(.avx)) .vmovss else .movss,8363 1 => return if (self.hasFeature(.avx)) .vmovss else .movss,
8145 2...4 => return if (self.hasFeature(.avx))8364 2...4 => return if (self.hasFeature(.avx))
src/arch/x86_64/Encoding.zig+13-10
...@@ -270,7 +270,7 @@ pub const Mnemonic = enum {...@@ -270,7 +270,7 @@ pub const Mnemonic = enum {
270 divps, divss,270 divps, divss,
271 maxps, maxss,271 maxps, maxss,
272 minps, minss,272 minps, minss,
273 movaps, movss, movups,273 movaps, movhlps, movss, movups,
274 mulps, mulss,274 mulps, mulss,
275 orps,275 orps,
276 pextrw, pinsrw,276 pextrw, pinsrw,
...@@ -303,6 +303,8 @@ pub const Mnemonic = enum {...@@ -303,6 +303,8 @@ pub const Mnemonic = enum {
303 // SSE3303 // SSE3
304 movddup, movshdup, movsldup,304 movddup, movshdup, movsldup,
305 // SSE4.1305 // SSE4.1
306 pextrb, pextrd, pextrq,
307 pinsrb, pinsrd, pinsrq,
306 roundpd, roundps, roundsd, roundss,308 roundpd, roundps, roundsd, roundss,
307 // AVX309 // AVX
308 vaddpd, vaddps, vaddsd, vaddss,310 vaddpd, vaddps, vaddsd, vaddss,
...@@ -311,13 +313,14 @@ pub const Mnemonic = enum {...@@ -311,13 +313,14 @@ pub const Mnemonic = enum {
311 vmaxpd, vmaxps, vmaxsd, vmaxss,313 vmaxpd, vmaxps, vmaxsd, vmaxss,
312 vminpd, vminps, vminsd, vminss,314 vminpd, vminps, vminsd, vminss,
313 vmovapd, vmovaps,315 vmovapd, vmovaps,
314 vmovddup,316 vmovddup, vmovhlps,
315 vmovsd,317 vmovsd,
316 vmovshdup, vmovsldup,318 vmovshdup, vmovsldup,
317 vmovss,319 vmovss,
318 vmovupd, vmovups,320 vmovupd, vmovups,
319 vmulpd, vmulps, vmulsd, vmulss,321 vmulpd, vmulps, vmulsd, vmulss,
320 vpextrw, vpinsrw,322 vpextrb, vpextrd, vpextrq, vpextrw,
323 vpinsrb, vpinsrd, vpinsrq, vpinsrw,
321 vpshufhw, vpshuflw,324 vpshufhw, vpshuflw,
322 vpsrld, vpsrlq, vpsrlw,325 vpsrld, vpsrlq, vpsrlw,
323 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,326 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,
...@@ -359,7 +362,7 @@ pub const Op = enum {...@@ -359,7 +362,7 @@ pub const Op = enum {
359 cl,362 cl,
360 r8, r16, r32, r64,363 r8, r16, r32, r64,
361 rm8, rm16, rm32, rm64,364 rm8, rm16, rm32, rm64,
362 r32_m16, r64_m16,365 r32_m8, r32_m16, r64_m16,
363 m8, m16, m32, m64, m80, m128, m256,366 m8, m16, m32, m64, m80, m128, m256,
364 rel8, rel16, rel32,367 rel8, rel16, rel32,
365 m,368 m,
...@@ -444,7 +447,7 @@ pub const Op = enum {...@@ -444,7 +447,7 @@ pub const Op = enum {
444 pub fn immBitSize(op: Op) u64 {447 pub fn immBitSize(op: Op) u64 {
445 return switch (op) {448 return switch (op) {
446 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,449 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
447 .al, .cl, .r8, .rm8 => unreachable,450 .al, .cl, .r8, .rm8, .r32_m8 => unreachable,
448 .ax, .r16, .rm16 => unreachable,451 .ax, .r16, .rm16 => unreachable,
449 .eax, .r32, .rm32, .r32_m16 => unreachable,452 .eax, .r32, .rm32, .r32_m16 => unreachable,
450 .rax, .r64, .rm64, .r64_m16 => unreachable,453 .rax, .r64, .rm64, .r64_m16 => unreachable,
...@@ -467,7 +470,7 @@ pub const Op = enum {...@@ -467,7 +470,7 @@ pub const Op = enum {
467 .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable,470 .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable,
468 .al, .cl, .r8, .rm8 => 8,471 .al, .cl, .r8, .rm8 => 8,
469 .ax, .r16, .rm16 => 16,472 .ax, .r16, .rm16 => 16,
470 .eax, .r32, .rm32, .r32_m16 => 32,473 .eax, .r32, .rm32, .r32_m8, .r32_m16 => 32,
471 .rax, .r64, .rm64, .r64_m16 => 64,474 .rax, .r64, .rm64, .r64_m16 => 64,
472 .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128,475 .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128,
473 .ymm, .ymm_m256 => 256,476 .ymm, .ymm_m256 => 256,
...@@ -480,7 +483,7 @@ pub const Op = enum {...@@ -480,7 +483,7 @@ pub const Op = enum {
480 .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable,483 .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable,
481 .rel8, .rel16, .rel32 => unreachable,484 .rel8, .rel16, .rel32 => unreachable,
482 .al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .xmm, .ymm => unreachable,485 .al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .xmm, .ymm => unreachable,
483 .m8, .rm8 => 8,486 .m8, .rm8, .r32_m8 => 8,
484 .m16, .rm16, .r32_m16, .r64_m16 => 16,487 .m16, .rm16, .r32_m16, .r64_m16 => 16,
485 .m32, .rm32, .xmm_m32 => 32,488 .m32, .rm32, .xmm_m32 => 32,
486 .m64, .rm64, .xmm_m64 => 64,489 .m64, .rm64, .xmm_m64 => 64,
...@@ -509,7 +512,7 @@ pub const Op = enum {...@@ -509,7 +512,7 @@ pub const Op = enum {
509 .al, .ax, .eax, .rax,512 .al, .ax, .eax, .rax,
510 .r8, .r16, .r32, .r64,513 .r8, .r16, .r32, .r64,
511 .rm8, .rm16, .rm32, .rm64,514 .rm8, .rm16, .rm32, .rm64,
512 .r32_m16, .r64_m16,515 .r32_m8, .r32_m16, .r64_m16,
513 .xmm, .xmm_m32, .xmm_m64, .xmm_m128,516 .xmm, .xmm_m32, .xmm_m64, .xmm_m128,
514 .ymm, .ymm_m256,517 .ymm, .ymm_m256,
515 => true,518 => true,
...@@ -535,7 +538,7 @@ pub const Op = enum {...@@ -535,7 +538,7 @@ pub const Op = enum {
535 // zig fmt: off538 // zig fmt: off
536 return switch (op) {539 return switch (op) {
537 .rm8, .rm16, .rm32, .rm64,540 .rm8, .rm16, .rm32, .rm64,
538 .r32_m16, .r64_m16,541 .r32_m8, .r32_m16, .r64_m16,
539 .m8, .m16, .m32, .m64, .m80, .m128, .m256,542 .m8, .m16, .m32, .m64, .m80, .m128, .m256,
540 .m,543 .m,
541 .xmm_m32, .xmm_m64, .xmm_m128,544 .xmm_m32, .xmm_m64, .xmm_m128,
...@@ -559,7 +562,7 @@ pub const Op = enum {...@@ -559,7 +562,7 @@ pub const Op = enum {
559 .al, .ax, .eax, .rax, .cl => .general_purpose,562 .al, .ax, .eax, .rax, .cl => .general_purpose,
560 .r8, .r16, .r32, .r64 => .general_purpose,563 .r8, .r16, .r32, .r64 => .general_purpose,
561 .rm8, .rm16, .rm32, .rm64 => .general_purpose,564 .rm8, .rm16, .rm32, .rm64 => .general_purpose,
562 .r32_m16, .r64_m16 => .general_purpose,565 .r32_m8, .r32_m16, .r64_m16 => .general_purpose,
563 .sreg => .segment,566 .sreg => .segment,
564 .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .floating_point,567 .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .floating_point,
565 .ymm, .ymm_m256 => .floating_point,568 .ymm, .ymm_m256 => .floating_point,
src/arch/x86_64/Lower.zig+22
...@@ -137,6 +137,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -137,6 +137,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
137 .minps,137 .minps,
138 .minss,138 .minss,
139 .movaps,139 .movaps,
140 .movhlps,
140 .movss,141 .movss,
141 .movups,142 .movups,
142 .mulps,143 .mulps,
...@@ -149,6 +150,8 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -149,6 +150,8 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
149 .subps,150 .subps,
150 .subss,151 .subss,
151 .ucomiss,152 .ucomiss,
153 .unpckhps,
154 .unpcklps,
152 .xorps,155 .xorps,
153156
154 .addpd,157 .addpd,
...@@ -187,12 +190,20 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -187,12 +190,20 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
187 .subpd,190 .subpd,
188 .subsd,191 .subsd,
189 .ucomisd,192 .ucomisd,
193 .unpckhpd,
194 .unpcklpd,
190 .xorpd,195 .xorpd,
191196
192 .movddup,197 .movddup,
193 .movshdup,198 .movshdup,
194 .movsldup,199 .movsldup,
195200
201 .pextrb,
202 .pextrd,
203 .pextrq,
204 .pinsrb,
205 .pinsrd,
206 .pinsrq,
196 .roundpd,207 .roundpd,
197 .roundps,208 .roundps,
198 .roundsd,209 .roundsd,
...@@ -221,6 +232,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -221,6 +232,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
221 .vmovapd,232 .vmovapd,
222 .vmovaps,233 .vmovaps,
223 .vmovddup,234 .vmovddup,
235 .vmovhlps,
224 .vmovsd,236 .vmovsd,
225 .vmovshdup,237 .vmovshdup,
226 .vmovsldup,238 .vmovsldup,
...@@ -231,7 +243,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -231,7 +243,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
231 .vmulps,243 .vmulps,
232 .vmulsd,244 .vmulsd,
233 .vmulss,245 .vmulss,
246 .vpextrb,
247 .vpextrd,
248 .vpextrq,
234 .vpextrw,249 .vpextrw,
250 .vpinsrb,
251 .vpinsrd,
252 .vpinsrq,
235 .vpinsrw,253 .vpinsrw,
236 .vpshufhw,254 .vpshufhw,
237 .vpshuflw,255 .vpshuflw,
...@@ -258,6 +276,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -258,6 +276,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
258 .vsubps,276 .vsubps,
259 .vsubsd,277 .vsubsd,
260 .vsubss,278 .vsubss,
279 .vunpckhpd,
280 .vunpckhps,
281 .vunpcklpd,
282 .vunpcklps,
261283
262 .vcvtph2ps,284 .vcvtph2ps,
263 .vcvtps2ph,285 .vcvtps2ph,
src/arch/x86_64/Mir.zig+44
...@@ -192,6 +192,8 @@ pub const Inst = struct {...@@ -192,6 +192,8 @@ pub const Inst = struct {
192 minss,192 minss,
193 /// Move aligned packed single-precision floating-point values193 /// Move aligned packed single-precision floating-point values
194 movaps,194 movaps,
195 /// Move packed single-precision floating-point values high to low
196 movhlps,
195 /// Move scalar single-precision floating-point value197 /// Move scalar single-precision floating-point value
196 movss,198 movss,
197 /// Move unaligned packed single-precision floating-point values199 /// Move unaligned packed single-precision floating-point values
...@@ -216,6 +218,10 @@ pub const Inst = struct {...@@ -216,6 +218,10 @@ pub const Inst = struct {
216 subss,218 subss,
217 /// Unordered compare scalar single-precision floating-point values219 /// Unordered compare scalar single-precision floating-point values
218 ucomiss,220 ucomiss,
221 /// Unpack and interleave high packed single-precision floating-point values
222 unpckhps,
223 /// Unpack and interleave low packed single-precision floating-point values
224 unpcklps,
219 /// Bitwise logical xor of packed single precision floating-point values225 /// Bitwise logical xor of packed single precision floating-point values
220 xorps,226 xorps,
221227
...@@ -291,6 +297,10 @@ pub const Inst = struct {...@@ -291,6 +297,10 @@ pub const Inst = struct {
291 subsd,297 subsd,
292 /// Unordered compare scalar double-precision floating-point values298 /// Unordered compare scalar double-precision floating-point values
293 ucomisd,299 ucomisd,
300 /// Unpack and interleave high packed double-precision floating-point values
301 unpckhpd,
302 /// Unpack and interleave low packed double-precision floating-point values
303 unpcklpd,
294 /// Bitwise logical xor of packed double precision floating-point values304 /// Bitwise logical xor of packed double precision floating-point values
295 xorpd,305 xorpd,
296306
...@@ -301,6 +311,18 @@ pub const Inst = struct {...@@ -301,6 +311,18 @@ pub const Inst = struct {
301 /// Replicate single floating-point values311 /// Replicate single floating-point values
302 movsldup,312 movsldup,
303313
314 /// Extract Byte
315 pextrb,
316 /// Extract Doubleword
317 pextrd,
318 /// Extract Quadword
319 pextrq,
320 /// Insert Byte
321 pinsrb,
322 /// Insert Doubleword
323 pinsrd,
324 /// Insert Quadword
325 pinsrq,
304 /// Round packed double-precision floating-point values326 /// Round packed double-precision floating-point values
305 roundpd,327 roundpd,
306 /// Round packed single-precision floating-point values328 /// Round packed single-precision floating-point values
...@@ -354,6 +376,8 @@ pub const Inst = struct {...@@ -354,6 +376,8 @@ pub const Inst = struct {
354 vmovapd,376 vmovapd,
355 /// Move aligned packed single-precision floating-point values377 /// Move aligned packed single-precision floating-point values
356 vmovaps,378 vmovaps,
379 /// Move packed single-precision floating-point values high to low
380 vmovhlps,
357 /// Replicate double floating-point values381 /// Replicate double floating-point values
358 vmovddup,382 vmovddup,
359 /// Move or merge scalar double-precision floating-point value383 /// Move or merge scalar double-precision floating-point value
...@@ -376,8 +400,20 @@ pub const Inst = struct {...@@ -376,8 +400,20 @@ pub const Inst = struct {
376 vmulsd,400 vmulsd,
377 /// Multiply scalar single-precision floating-point values401 /// Multiply scalar single-precision floating-point values
378 vmulss,402 vmulss,
403 /// Extract Byte
404 vpextrb,
405 /// Extract Doubleword
406 vpextrd,
407 /// Extract Quadword
408 vpextrq,
379 /// Extract word409 /// Extract word
380 vpextrw,410 vpextrw,
411 /// Insert Byte
412 vpinsrb,
413 /// Insert Doubleword
414 vpinsrd,
415 /// Insert Quadword
416 vpinsrq,
381 /// Insert word417 /// Insert word
382 vpinsrw,418 vpinsrw,
383 /// Shuffle packed high words419 /// Shuffle packed high words
...@@ -430,6 +466,14 @@ pub const Inst = struct {...@@ -430,6 +466,14 @@ pub const Inst = struct {
430 vsubsd,466 vsubsd,
431 /// Subtract scalar single-precision floating-point values467 /// Subtract scalar single-precision floating-point values
432 vsubss,468 vsubss,
469 /// Unpack and interleave high packed double-precision floating-point values
470 vunpckhpd,
471 /// Unpack and interleave high packed single-precision floating-point values
472 vunpckhps,
473 /// Unpack and interleave low packed double-precision floating-point values
474 vunpcklpd,
475 /// Unpack and interleave low packed single-precision floating-point values
476 vunpcklps,
433477
434 /// Convert 16-bit floating-point values to single-precision floating-point values478 /// Convert 16-bit floating-point values to single-precision floating-point values
435 vcvtph2ps,479 vcvtph2ps,
src/arch/x86_64/encodings.zig+20
...@@ -865,6 +865,8 @@ pub const table = [_]Entry{...@@ -865,6 +865,8 @@ pub const table = [_]Entry{
865 .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse },865 .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse },
866 .{ .movaps, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x29 }, 0, .none, .sse },866 .{ .movaps, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x29 }, 0, .none, .sse },
867867
868 .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse },
869
868 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse },870 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse },
869 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse },871 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse },
870872
...@@ -988,8 +990,16 @@ pub const table = [_]Entry{...@@ -988,8 +990,16 @@ pub const table = [_]Entry{
988 .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 },990 .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 },
989991
990 // SSE4.1992 // SSE4.1
993 .{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 },
994 .{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 },
995 .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 },
996
991 .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 },997 .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 },
992998
999 .{ .pinsrb, .rmi, &.{ .xmm, .r32_m8, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x20 }, 0, .none, .sse4_1 },
1000 .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 },
1001 .{ .pinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .long, .sse4_1 },
1002
993 .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 },1003 .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 },
9941004
995 .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 },1005 .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 },
...@@ -1062,6 +1072,8 @@ pub const table = [_]Entry{...@@ -1062,6 +1072,8 @@ pub const table = [_]Entry{
1062 .{ .vmovddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_128_wig, .avx },1072 .{ .vmovddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_128_wig, .avx },
1063 .{ .vmovddup, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_256_wig, .avx },1073 .{ .vmovddup, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_256_wig, .avx },
10641074
1075 .{ .vmovhlps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .vex_128_wig, .avx },
1076
1065 .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },1077 .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },
1066 .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },1078 .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },
1067 .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx },1079 .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx },
...@@ -1098,9 +1110,17 @@ pub const table = [_]Entry{...@@ -1098,9 +1110,17 @@ pub const table = [_]Entry{
10981110
1099 .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx },1111 .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx },
11001112
1113 .{ .vpextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .vex_128_w0, .avx },
1114 .{ .vpextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w0, .avx },
1115 .{ .vpextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w1, .avx },
1116
1101 .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx },1117 .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx },
1102 .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx },1118 .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx },
11031119
1120 .{ .vpinsrb, .rmi, &.{ .xmm, .r32_m8, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x20 }, 0, .vex_128_w0, .avx },
1121 .{ .vpinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .vex_128_w0, .avx },
1122 .{ .vpinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .vex_128_w1, .avx },
1123
1104 .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx },1124 .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx },
11051125
1106 .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx },1126 .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx },
test/behavior/floatop.zig+11-11
...@@ -8,6 +8,8 @@ const has_f80_rt = switch (builtin.cpu.arch) {...@@ -8,6 +8,8 @@ const has_f80_rt = switch (builtin.cpu.arch) {
8 .x86_64, .x86 => true,8 .x86_64, .x86 => true,
9 else => false,9 else => false,
10};10};
11const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and
12 !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c);
1113
12const epsilon_16 = 0.001;14const epsilon_16 = 0.001;
13const epsilon = 0.000001;15const epsilon = 0.000001;
...@@ -52,8 +54,7 @@ fn testFloatComparisons() !void {...@@ -52,8 +54,7 @@ fn testFloatComparisons() !void {
52}54}
5355
54test "different sized float comparisons" {56test "different sized float comparisons" {
55 if (builtin.zig_backend == .stage2_x86_64 and57 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
56 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO59 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO60 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -152,7 +153,7 @@ fn testSqrtWithVectors() !void {...@@ -152,7 +153,7 @@ fn testSqrtWithVectors() !void {
152}153}
153154
154test "more @sqrt f16 tests" {155test "more @sqrt f16 tests" {
155 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO156 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO157 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
157 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO158 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
158 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO159 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -202,7 +203,7 @@ fn testSqrtLegacy(comptime T: type, x: T) !void {...@@ -202,7 +203,7 @@ fn testSqrtLegacy(comptime T: type, x: T) !void {
202}203}
203204
204test "@sin" {205test "@sin" {
205 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO206 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO207 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
207 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO208 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
208 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -241,7 +242,7 @@ fn testSinWithVectors() !void {...@@ -241,7 +242,7 @@ fn testSinWithVectors() !void {
241}242}
242243
243test "@cos" {244test "@cos" {
244 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO245 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
245 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO246 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
247 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -280,7 +281,7 @@ fn testCosWithVectors() !void {...@@ -280,7 +281,7 @@ fn testCosWithVectors() !void {
280}281}
281282
282test "@exp" {283test "@exp" {
283 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO284 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
284 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO285 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
285 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
286 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -318,7 +319,7 @@ fn testExpWithVectors() !void {...@@ -318,7 +319,7 @@ fn testExpWithVectors() !void {
318}319}
319320
320test "@exp2" {321test "@exp2" {
321 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO322 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
322 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO323 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
323 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO324 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
324 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO325 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -403,7 +404,7 @@ test "@log with @vectors" {...@@ -403,7 +404,7 @@ test "@log with @vectors" {
403}404}
404405
405test "@log2" {406test "@log2" {
406 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO407 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
407 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO408 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
408 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO410 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -445,7 +446,7 @@ fn testLog2WithVectors() !void {...@@ -445,7 +446,7 @@ fn testLog2WithVectors() !void {
445}446}
446447
447test "@log10" {448test "@log10" {
448 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO449 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
449 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO450 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
450 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO451 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
451 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO452 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -881,7 +882,7 @@ fn testTruncLegacy(comptime T: type, x: T) !void {...@@ -881,7 +882,7 @@ fn testTruncLegacy(comptime T: type, x: T) !void {
881}882}
882883
883test "negation f16" {884test "negation f16" {
884 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO885 if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO
885 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO886 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
886 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO887 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
887 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO888 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1040,7 +1041,6 @@ test "comptime_float zero divided by zero produces zero" {...@@ -1040,7 +1041,6 @@ test "comptime_float zero divided by zero produces zero" {
1040}1041}
10411042
1042test "nan negation f16" {1043test "nan negation f16" {
1043 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1044 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1044 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1045 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1045 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1046 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1046 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/muladd.zig+4-4
...@@ -2,11 +2,11 @@ const std = @import("std");...@@ -2,11 +2,11 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5const stage2_x86_64_without_hardware_fma_support = builtin.zig_backend == .stage2_x86_64 and5const no_x86_64_hardware_fma_support = builtin.zig_backend == .stage2_x86_64 and
6 !std.Target.x86.featureSetHas(builtin.cpu.features, .fma);6 !std.Target.x86.featureSetHas(builtin.cpu.features, .fma);
77
8test "@mulAdd" {8test "@mulAdd" {
9 if (stage2_x86_64_without_hardware_fma_support) return error.SkipZigTest; // TODO9 if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -120,7 +120,7 @@ fn vector32() !void {...@@ -120,7 +120,7 @@ fn vector32() !void {
120120
121test "vector f32" {121test "vector f32" {
122 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO122 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
123 if (stage2_x86_64_without_hardware_fma_support) return error.SkipZigTest; // TODO123 if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
125 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO125 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO126 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -143,7 +143,7 @@ fn vector64() !void {...@@ -143,7 +143,7 @@ fn vector64() !void {
143143
144test "vector f64" {144test "vector f64" {
145 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO145 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
146 if (stage2_x86_64_without_hardware_fma_support) return error.SkipZigTest; // TODO146 if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO
147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO