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 {
28002800 const result = result: {
28012801 const tag = self.air.instructions.items(.tag)[inst];
28022802 const dst_ty = self.air.typeOfIndex(inst);
2803 if (dst_ty.zigTypeTag() == .Float)
2804 break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs);
2803 switch (dst_ty.zigTypeTag()) {
2804 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
2805 else => {},
2806 }
28052807
28062808 const dst_info = dst_ty.intInfo(self.target.*);
28072809 var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) {
......@@ -6531,6 +6533,15 @@ fn genBinOp(
65316533 => if (self.hasFeature(.avx)) .{ .vp_b, .sub } else .{ .p_b, .sub },
65326534 else => null,
65336535 },
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 },
65346545 else => null,
65356546 },
65366547 16 => switch (lhs_ty.vectorLen()) {
......@@ -6541,6 +6552,21 @@ fn genBinOp(
65416552 .sub,
65426553 .subwrap,
65436554 => 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,
65446570 else => null,
65456571 },
65466572 else => null,
......@@ -6553,6 +6579,26 @@ fn genBinOp(
65536579 .sub,
65546580 .subwrap,
65556581 => 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,
65566602 else => null,
65576603 },
65586604 else => null,
......@@ -6567,6 +6613,15 @@ fn genBinOp(
65676613 => if (self.hasFeature(.avx)) .{ .vp_q, .sub } else .{ .p_q, .sub },
65686614 else => null,
65696615 },
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 },
65706625 else => null,
65716626 },
65726627 else => null,
src/arch/x86_64/Encoding.zig+3
......@@ -264,6 +264,7 @@ pub const Mnemonic = enum {
264264 movd, movq,
265265 paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw,
266266 pand, pandn, por, pxor,
267 pmulhw, pmullw,
267268 psubb, psubd, psubq, psubsb, psubsw, psubusb, psubusw, psubw,
268269 // SSE
269270 addps, addss,
......@@ -317,6 +318,7 @@ pub const Mnemonic = enum {
317318 insertps,
318319 pextrb, pextrd, pextrq,
319320 pinsrb, pinsrd, pinsrq,
321 pmulld,
320322 roundpd, roundps, roundsd, roundss,
321323 // AVX
322324 vaddpd, vaddps, vaddsd, vaddss,
......@@ -347,6 +349,7 @@ pub const Mnemonic = enum {
347349 vpand, vpandn,
348350 vpextrb, vpextrd, vpextrq, vpextrw,
349351 vpinsrb, vpinsrd, vpinsrq, vpinsrw,
352 vpmulhw, vpmulld, vpmullw,
350353 vpor,
351354 vpshufhw, vpshuflw,
352355 vpsrld, vpsrlq, vpsrlw,
src/arch/x86_64/Mir.zig+4
......@@ -453,6 +453,10 @@ pub const Inst = struct {
453453 /// Bitwise logical and not of packed single-precision floating-point values
454454 /// Bitwise logical and not of packed double-precision floating-point values
455455 andn,
456 /// Multiply packed signed integers and store low result
457 mull,
458 /// Multiply packed signed integers and store high result
459 mulh,
456460 /// Subtract packed signed integers with signed saturation
457461 subs,
458462 /// Subtract packed unsigned integers with unsigned saturation
src/arch/x86_64/encodings.zig+21-3
......@@ -1011,6 +1011,10 @@ pub const table = [_]Entry{
10111011
10121012 .{ .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
10141018 .{ .por, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .none, .sse2 },
10151019
10161020 .{ .pshufhw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf3, 0x0f, 0x70 }, 0, .none, .sse2 },
......@@ -1087,6 +1091,8 @@ pub const table = [_]Entry{
10871091 .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 },
10881092 .{ .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
10901096 .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 },
10911097
10921098 .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 },
......@@ -1312,6 +1318,12 @@ pub const table = [_]Entry{
13121318
13131319 .{ .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
13151327 .{ .vpor, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_128_wig, .avx },
13161328
13171329 .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx },
......@@ -1418,9 +1430,9 @@ pub const table = [_]Entry{
14181430 .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma },
14191431
14201432 // AVX2
1421 .{ .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 },
1423 .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 },
1433 .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 },
1434 .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 },
1435 .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 },
14241436
14251437 .{ .vpaddb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_256_wig, .avx2 },
14261438 .{ .vpaddw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_256_wig, .avx2 },
......@@ -1437,6 +1449,12 @@ pub const table = [_]Entry{
14371449
14381450 .{ .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
14401458 .{ .vpor, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_256_wig, .avx2 },
14411459
14421460 .{ .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" {
2626
2727test "vector wrap operators" {
2828 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
3031 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
3132 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
3233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO