| author | |
| committer | |
| log | f39ff6cc68ab7a0d8ef349d4d930118890c19b01 |
| tree | 8417a0902fdad49eb9c4e97ee7a762593ee5732e |
| parent | bd771bec49fbb7845ad2635c0dd13aa971a81fee |
5 files changed, 87 insertions(+), 6 deletions(-)
src/arch/x86_64/CodeGen.zig+57-2| ... | @@ -2800,8 +2800,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2800,8 +2800,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 2800 | const result = result: { | 2800 | const result = result: { |
| 2801 | const tag = self.air.instructions.items(.tag)[inst]; | 2801 | const tag = self.air.instructions.items(.tag)[inst]; |
| 2802 | const dst_ty = self.air.typeOfIndex(inst); | 2802 | const dst_ty = self.air.typeOfIndex(inst); |
| 2803 | if (dst_ty.zigTypeTag() == .Float) | 2803 | switch (dst_ty.zigTypeTag()) { |
| 2804 | break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); | 2804 | .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), |
| 2805 | else => {}, | ||
| 2806 | } | ||
| 2805 | 2807 | ||
| 2806 | const dst_info = dst_ty.intInfo(self.target.*); | 2808 | const dst_info = dst_ty.intInfo(self.target.*); |
| 2807 | var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { | 2809 | var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { |
| ... | @@ -6531,6 +6533,15 @@ fn genBinOp( | ... | @@ -6531,6 +6533,15 @@ fn genBinOp( |
| 6531 | => if (self.hasFeature(.avx)) .{ .vp_b, .sub } else .{ .p_b, .sub }, | 6533 | => if (self.hasFeature(.avx)) .{ .vp_b, .sub } else .{ .p_b, .sub }, |
| 6532 | else => null, | 6534 | else => null, |
| 6533 | }, | 6535 | }, |
| 6536 | 17...32 => switch (air_tag) { | ||
| 6537 | .add, | ||
| 6538 | .addwrap, | ||
| 6539 | => if (self.hasFeature(.avx2)) .{ .vp_b, .add } else null, | ||
| 6540 | .sub, | ||
| 6541 | .subwrap, | ||
| 6542 | => if (self.hasFeature(.avx2)) .{ .vp_b, .sub } else null, | ||
| 6543 | else => null, | ||
| 6544 | }, | ||
| 6534 | else => null, | 6545 | else => null, |
| 6535 | }, | 6546 | }, |
| 6536 | 16 => switch (lhs_ty.vectorLen()) { | 6547 | 16 => switch (lhs_ty.vectorLen()) { |
| ... | @@ -6541,6 +6552,21 @@ fn genBinOp( | ... | @@ -6541,6 +6552,21 @@ fn genBinOp( |
| 6541 | .sub, | 6552 | .sub, |
| 6542 | .subwrap, | 6553 | .subwrap, |
| 6543 | => if (self.hasFeature(.avx)) .{ .vp_w, .sub } else .{ .p_w, .sub }, | 6554 | => if (self.hasFeature(.avx)) .{ .vp_w, .sub } else .{ .p_w, .sub }, |
| 6555 | .mul, | ||
| 6556 | .mulwrap, | ||
| 6557 | => if (self.hasFeature(.avx)) .{ .vp_w, .mull } else .{ .p_d, .mull }, | ||
| 6558 | else => null, | ||
| 6559 | }, | ||
| 6560 | 9...16 => switch (air_tag) { | ||
| 6561 | .add, | ||
| 6562 | .addwrap, | ||
| 6563 | => if (self.hasFeature(.avx2)) .{ .vp_w, .add } else null, | ||
| 6564 | .sub, | ||
| 6565 | .subwrap, | ||
| 6566 | => if (self.hasFeature(.avx2)) .{ .vp_w, .sub } else null, | ||
| 6567 | .mul, | ||
| 6568 | .mulwrap, | ||
| 6569 | => if (self.hasFeature(.avx2)) .{ .vp_w, .mull } else null, | ||
| 6544 | else => null, | 6570 | else => null, |
| 6545 | }, | 6571 | }, |
| 6546 | else => null, | 6572 | else => null, |
| ... | @@ -6553,6 +6579,26 @@ fn genBinOp( | ... | @@ -6553,6 +6579,26 @@ fn genBinOp( |
| 6553 | .sub, | 6579 | .sub, |
| 6554 | .subwrap, | 6580 | .subwrap, |
| 6555 | => if (self.hasFeature(.avx)) .{ .vp_d, .sub } else .{ .p_d, .sub }, | 6581 | => if (self.hasFeature(.avx)) .{ .vp_d, .sub } else .{ .p_d, .sub }, |
| 6582 | .mul, | ||
| 6583 | .mulwrap, | ||
| 6584 | => if (self.hasFeature(.avx)) | ||
| 6585 | .{ .vp_d, .mull } | ||
| 6586 | else if (self.hasFeature(.sse4_1)) | ||
| 6587 | .{ .p_d, .mull } | ||
| 6588 | else | ||
| 6589 | null, | ||
| 6590 | else => null, | ||
| 6591 | }, | ||
| 6592 | 5...8 => switch (air_tag) { | ||
| 6593 | .add, | ||
| 6594 | .addwrap, | ||
| 6595 | => if (self.hasFeature(.avx2)) .{ .vp_d, .add } else null, | ||
| 6596 | .sub, | ||
| 6597 | .subwrap, | ||
| 6598 | => if (self.hasFeature(.avx2)) .{ .vp_d, .sub } else null, | ||
| 6599 | .mul, | ||
| 6600 | .mulwrap, | ||
| 6601 | => if (self.hasFeature(.avx2)) .{ .vp_d, .mull } else null, | ||
| 6556 | else => null, | 6602 | else => null, |
| 6557 | }, | 6603 | }, |
| 6558 | else => null, | 6604 | else => null, |
| ... | @@ -6567,6 +6613,15 @@ fn genBinOp( | ... | @@ -6567,6 +6613,15 @@ fn genBinOp( |
| 6567 | => if (self.hasFeature(.avx)) .{ .vp_q, .sub } else .{ .p_q, .sub }, | 6613 | => if (self.hasFeature(.avx)) .{ .vp_q, .sub } else .{ .p_q, .sub }, |
| 6568 | else => null, | 6614 | else => null, |
| 6569 | }, | 6615 | }, |
| 6616 | 3...4 => switch (air_tag) { | ||
| 6617 | .add, | ||
| 6618 | .addwrap, | ||
| 6619 | => if (self.hasFeature(.avx2)) .{ .vp_q, .add } else null, | ||
| 6620 | .sub, | ||
| 6621 | .subwrap, | ||
| 6622 | => if (self.hasFeature(.avx2)) .{ .vp_q, .sub } else null, | ||
| 6623 | else => null, | ||
| 6624 | }, | ||
| 6570 | else => null, | 6625 | else => null, |
| 6571 | }, | 6626 | }, |
| 6572 | else => null, | 6627 | else => null, |
src/arch/x86_64/Encoding.zig+3| ... | @@ -264,6 +264,7 @@ pub const Mnemonic = enum { | ... | @@ -264,6 +264,7 @@ pub const Mnemonic = enum { |
| 264 | movd, movq, | 264 | movd, movq, |
| 265 | paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw, | 265 | paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw, |
| 266 | pand, pandn, por, pxor, | 266 | pand, pandn, por, pxor, |
| 267 | pmulhw, pmullw, | ||
| 267 | psubb, psubd, psubq, psubsb, psubsw, psubusb, psubusw, psubw, | 268 | psubb, psubd, psubq, psubsb, psubsw, psubusb, psubusw, psubw, |
| 268 | // SSE | 269 | // SSE |
| 269 | addps, addss, | 270 | addps, addss, |
| ... | @@ -317,6 +318,7 @@ pub const Mnemonic = enum { | ... | @@ -317,6 +318,7 @@ pub const Mnemonic = enum { |
| 317 | insertps, | 318 | insertps, |
| 318 | pextrb, pextrd, pextrq, | 319 | pextrb, pextrd, pextrq, |
| 319 | pinsrb, pinsrd, pinsrq, | 320 | pinsrb, pinsrd, pinsrq, |
| 321 | pmulld, | ||
| 320 | roundpd, roundps, roundsd, roundss, | 322 | roundpd, roundps, roundsd, roundss, |
| 321 | // AVX | 323 | // AVX |
| 322 | vaddpd, vaddps, vaddsd, vaddss, | 324 | vaddpd, vaddps, vaddsd, vaddss, |
| ... | @@ -347,6 +349,7 @@ pub const Mnemonic = enum { | ... | @@ -347,6 +349,7 @@ pub const Mnemonic = enum { |
| 347 | vpand, vpandn, | 349 | vpand, vpandn, |
| 348 | vpextrb, vpextrd, vpextrq, vpextrw, | 350 | vpextrb, vpextrd, vpextrq, vpextrw, |
| 349 | vpinsrb, vpinsrd, vpinsrq, vpinsrw, | 351 | vpinsrb, vpinsrd, vpinsrq, vpinsrw, |
| 352 | vpmulhw, vpmulld, vpmullw, | ||
| 350 | vpor, | 353 | vpor, |
| 351 | vpshufhw, vpshuflw, | 354 | vpshufhw, vpshuflw, |
| 352 | vpsrld, vpsrlq, vpsrlw, | 355 | vpsrld, vpsrlq, vpsrlw, |
src/arch/x86_64/Mir.zig+4| ... | @@ -453,6 +453,10 @@ pub const Inst = struct { | ... | @@ -453,6 +453,10 @@ pub const Inst = struct { |
| 453 | /// Bitwise logical and not of packed single-precision floating-point values | 453 | /// Bitwise logical and not of packed single-precision floating-point values |
| 454 | /// Bitwise logical and not of packed double-precision floating-point values | 454 | /// Bitwise logical and not of packed double-precision floating-point values |
| 455 | andn, | 455 | andn, |
| 456 | /// Multiply packed signed integers and store low result | ||
| 457 | mull, | ||
| 458 | /// Multiply packed signed integers and store high result | ||
| 459 | mulh, | ||
| 456 | /// Subtract packed signed integers with signed saturation | 460 | /// Subtract packed signed integers with signed saturation |
| 457 | subs, | 461 | subs, |
| 458 | /// Subtract packed unsigned integers with unsigned saturation | 462 | /// Subtract packed unsigned integers with unsigned saturation |
src/arch/x86_64/encodings.zig+21-3| ... | @@ -1011,6 +1011,10 @@ pub const table = [_]Entry{ | ... | @@ -1011,6 +1011,10 @@ pub const table = [_]Entry{ |
| 1011 | 1011 | ||
| 1012 | .{ .pinsrw, .rmi, &.{ .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .none, .sse2 }, | 1012 | .{ .pinsrw, .rmi, &.{ .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .none, .sse2 }, |
| 1013 | 1013 | ||
| 1014 | .{ .pmulhw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .none, .sse2 }, | ||
| 1015 | |||
| 1016 | .{ .pmullw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .none, .sse2 }, | ||
| 1017 | |||
| 1014 | .{ .por, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .none, .sse2 }, | 1018 | .{ .por, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .none, .sse2 }, |
| 1015 | 1019 | ||
| 1016 | .{ .pshufhw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf3, 0x0f, 0x70 }, 0, .none, .sse2 }, | 1020 | .{ .pshufhw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf3, 0x0f, 0x70 }, 0, .none, .sse2 }, |
| ... | @@ -1087,6 +1091,8 @@ pub const table = [_]Entry{ | ... | @@ -1087,6 +1091,8 @@ pub const table = [_]Entry{ |
| 1087 | .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 }, | 1091 | .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 }, |
| 1088 | .{ .pinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .long, .sse4_1 }, | 1092 | .{ .pinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .long, .sse4_1 }, |
| 1089 | 1093 | ||
| 1094 | .{ .pmulld, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .none, .sse4_1 }, | ||
| 1095 | |||
| 1090 | .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 }, | 1096 | .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 }, |
| 1091 | 1097 | ||
| 1092 | .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 }, | 1098 | .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 }, |
| ... | @@ -1312,6 +1318,12 @@ pub const table = [_]Entry{ | ... | @@ -1312,6 +1318,12 @@ pub const table = [_]Entry{ |
| 1312 | 1318 | ||
| 1313 | .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx }, | 1319 | .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx }, |
| 1314 | 1320 | ||
| 1321 | .{ .vpmulhw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .vex_128_wig, .avx }, | ||
| 1322 | |||
| 1323 | .{ .vpmulld, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .vex_128_wig, .avx }, | ||
| 1324 | |||
| 1325 | .{ .vpmullw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .vex_128_wig, .avx }, | ||
| 1326 | |||
| 1315 | .{ .vpor, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_128_wig, .avx }, | 1327 | .{ .vpor, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_128_wig, .avx }, |
| 1316 | 1328 | ||
| 1317 | .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx }, | 1329 | .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx }, |
| ... | @@ -1418,9 +1430,9 @@ pub const table = [_]Entry{ | ... | @@ -1418,9 +1430,9 @@ pub const table = [_]Entry{ |
| 1418 | .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma }, | 1430 | .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma }, |
| 1419 | 1431 | ||
| 1420 | // AVX2 | 1432 | // AVX2 |
| 1421 | .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 }, | 1433 | .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 }, |
| 1422 | .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 }, | 1434 | .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 }, |
| 1423 | .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 }, | 1435 | .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 }, |
| 1424 | 1436 | ||
| 1425 | .{ .vpaddb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_256_wig, .avx2 }, | 1437 | .{ .vpaddb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_256_wig, .avx2 }, |
| 1426 | .{ .vpaddw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_256_wig, .avx2 }, | 1438 | .{ .vpaddw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_256_wig, .avx2 }, |
| ... | @@ -1437,6 +1449,12 @@ pub const table = [_]Entry{ | ... | @@ -1437,6 +1449,12 @@ pub const table = [_]Entry{ |
| 1437 | 1449 | ||
| 1438 | .{ .vpandn, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_256_wig, .avx2 }, | 1450 | .{ .vpandn, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_256_wig, .avx2 }, |
| 1439 | 1451 | ||
| 1452 | .{ .vpmulhw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .vex_256_wig, .avx }, | ||
| 1453 | |||
| 1454 | .{ .vpmulld, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .vex_256_wig, .avx }, | ||
| 1455 | |||
| 1456 | .{ .vpmullw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .vex_256_wig, .avx }, | ||
| 1457 | |||
| 1440 | .{ .vpor, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_256_wig, .avx2 }, | 1458 | .{ .vpor, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_256_wig, .avx2 }, |
| 1441 | 1459 | ||
| 1442 | .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 }, | 1460 | .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 }, |
test/behavior/vector.zig+2-1| ... | @@ -26,7 +26,8 @@ test "implicit cast vector to array - bool" { | ... | @@ -26,7 +26,8 @@ test "implicit cast vector to array - bool" { |
| 26 | 26 | ||
| 27 | test "vector wrap operators" { | 27 | test "vector wrap operators" { |
| 28 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 28 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 29 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 29 | if (builtin.zig_backend == .stage2_x86_64 and |
| 30 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 30 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 31 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 32 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 33 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |