authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 01:15:37-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 03:07:51-04:00
logf39ff6cc68ab7a0d8ef349d4d930118890c19b01
tree8417a0902fdad49eb9c4e97ee7a762593ee5732e
parentbd771bec49fbb7845ad2635c0dd13aa971a81fee

x86_64: implement integer vector mul


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 }
28052807
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 // SSE269 // 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 // AVX323 // 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 values453 /// Bitwise logical and not of packed single-precision floating-point values
454 /// Bitwise logical and not of packed double-precision floating-point values454 /// 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 saturation460 /// Subtract packed signed integers with signed saturation
457 subs,461 subs,
458 /// Subtract packed unsigned integers with unsigned saturation462 /// 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{
10111011
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 },
10131013
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 },
10151019
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 },
10891093
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 },
10911097
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{
13121318
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 },
13141320
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 },
13161328
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 },
14191431
1420 // AVX21432 // 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 },
14241436
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{
14371449
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 },
14391451
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 },
14411459
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" {
2626
27test "vector wrap operators" {27test "vector wrap operators" {
28 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO28 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
29 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO29 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; // TODO31 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
31 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO32 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
32 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO33 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO