authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 02:55:41-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 03:07:51-04:00
logcea9ac772a518ff249d47fc2cb7b2776c786ac07
tree0a9d5247caca2bbfa2a5ef61e025a4da2c6b435d
parent40457a3696da015fe1396d6c84191b83731910db

x86_64: implement integer vector min/max


4 files changed, 170 insertions(+), 0 deletions(-)

src/arch/x86_64/CodeGen.zig+100
......@@ -6534,6 +6534,34 @@ fn genBinOp(
65346534 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
65356535 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
65366536 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
6537 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6538 .signed => if (self.hasFeature(.avx))
6539 .{ .vp_b, .mins }
6540 else if (self.hasFeature(.sse4_1))
6541 .{ .p_b, .mins }
6542 else
6543 null,
6544 .unsigned => if (self.hasFeature(.avx))
6545 .{ .vp_b, .minu }
6546 else if (self.hasFeature(.sse4_1))
6547 .{ .p_b, .minu }
6548 else
6549 null,
6550 },
6551 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6552 .signed => if (self.hasFeature(.avx))
6553 .{ .vp_b, .maxs }
6554 else if (self.hasFeature(.sse4_1))
6555 .{ .p_b, .maxs }
6556 else
6557 null,
6558 .unsigned => if (self.hasFeature(.avx))
6559 .{ .vp_b, .maxu }
6560 else if (self.hasFeature(.sse4_1))
6561 .{ .p_b, .maxu }
6562 else
6563 null,
6564 },
65376565 else => null,
65386566 },
65396567 17...32 => switch (air_tag) {
......@@ -6546,6 +6574,14 @@ fn genBinOp(
65466574 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
65476575 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
65486576 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
6577 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6578 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null,
6579 .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null,
6580 },
6581 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6582 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null,
6583 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null,
6584 },
65496585 else => null,
65506586 },
65516587 else => null,
......@@ -6564,6 +6600,26 @@ fn genBinOp(
65646600 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
65656601 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
65666602 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
6603 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6604 .signed => if (self.hasFeature(.avx))
6605 .{ .vp_w, .mins }
6606 else
6607 .{ .p_w, .mins },
6608 .unsigned => if (self.hasFeature(.avx))
6609 .{ .vp_w, .minu }
6610 else
6611 .{ .p_w, .minu },
6612 },
6613 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6614 .signed => if (self.hasFeature(.avx))
6615 .{ .vp_w, .maxs }
6616 else
6617 .{ .p_w, .maxs },
6618 .unsigned => if (self.hasFeature(.avx))
6619 .{ .vp_w, .maxu }
6620 else
6621 .{ .p_w, .maxu },
6622 },
65676623 else => null,
65686624 },
65696625 9...16 => switch (air_tag) {
......@@ -6579,6 +6635,14 @@ fn genBinOp(
65796635 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
65806636 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
65816637 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
6638 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6639 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null,
6640 .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null,
6641 },
6642 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6643 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null,
6644 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null,
6645 },
65826646 else => null,
65836647 },
65846648 else => null,
......@@ -6602,6 +6666,34 @@ fn genBinOp(
66026666 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
66036667 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
66046668 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
6669 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6670 .signed => if (self.hasFeature(.avx))
6671 .{ .vp_d, .mins }
6672 else if (self.hasFeature(.sse4_1))
6673 .{ .p_d, .mins }
6674 else
6675 null,
6676 .unsigned => if (self.hasFeature(.avx))
6677 .{ .vp_d, .minu }
6678 else if (self.hasFeature(.sse4_1))
6679 .{ .p_d, .minu }
6680 else
6681 null,
6682 },
6683 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6684 .signed => if (self.hasFeature(.avx))
6685 .{ .vp_d, .maxs }
6686 else if (self.hasFeature(.sse4_1))
6687 .{ .p_d, .maxs }
6688 else
6689 null,
6690 .unsigned => if (self.hasFeature(.avx))
6691 .{ .vp_d, .maxu }
6692 else if (self.hasFeature(.sse4_1))
6693 .{ .p_d, .maxu }
6694 else
6695 null,
6696 },
66056697 else => null,
66066698 },
66076699 5...8 => switch (air_tag) {
......@@ -6617,6 +6709,14 @@ fn genBinOp(
66176709 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
66186710 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
66196711 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
6712 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6713 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null,
6714 .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null,
6715 },
6716 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6717 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null,
6718 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null,
6719 },
66206720 else => null,
66216721 },
66226722 else => null,
src/arch/x86_64/Encoding.zig+4
......@@ -280,6 +280,7 @@ pub const Mnemonic = enum {
280280 mulps, mulss,
281281 orps,
282282 pextrw, pinsrw,
283 pmaxsw, pmaxub, pminsw, pminub,
283284 shufps,
284285 sqrtps, sqrtss,
285286 subps, subss,
......@@ -318,6 +319,7 @@ pub const Mnemonic = enum {
318319 insertps,
319320 pextrb, pextrd, pextrq,
320321 pinsrb, pinsrd, pinsrq,
322 pmaxsb, pmaxsd, pmaxud, pmaxuw, pminsb, pminsd, pminud, pminuw,
321323 pmulld,
322324 roundpd, roundps, roundsd, roundss,
323325 // AVX
......@@ -349,6 +351,8 @@ pub const Mnemonic = enum {
349351 vpand, vpandn,
350352 vpextrb, vpextrd, vpextrq, vpextrw,
351353 vpinsrb, vpinsrd, vpinsrq, vpinsrw,
354 vpmaxsb, vpmaxsd, vpmaxsw, vpmaxub, vpmaxud, vpmaxuw,
355 vpminsb, vpminsd, vpminsw, vpminub, vpminud, vpminuw,
352356 vpmulhw, vpmulld, vpmullw,
353357 vpor,
354358 vpshufhw, vpshuflw,
src/arch/x86_64/Mir.zig+8
......@@ -453,6 +453,14 @@ 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 /// Maximum of packed signed integers
457 maxs,
458 /// Maximum of packed unsigned integers
459 maxu,
460 /// Minimum of packed signed integers
461 mins,
462 /// Minimum of packed unsigned integers
463 minu,
456464 /// Multiply packed signed integers and store low result
457465 mull,
458466 /// Multiply packed signed integers and store high result
src/arch/x86_64/encodings.zig+58
......@@ -1011,6 +1011,14 @@ pub const table = [_]Entry{
10111011
10121012 .{ .pinsrw, .rmi, &.{ .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .none, .sse2 },
10131013
1014 .{ .pmaxsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xee }, 0, .none, .sse2 },
1015
1016 .{ .pmaxub, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xde }, 0, .none, .sse2 },
1017
1018 .{ .pminsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xea }, 0, .none, .sse2 },
1019
1020 .{ .pminub, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xda }, 0, .none, .sse2 },
1021
10141022 .{ .pmulhw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .none, .sse2 },
10151023
10161024 .{ .pmullw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .none, .sse2 },
......@@ -1091,6 +1099,20 @@ pub const table = [_]Entry{
10911099 .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 },
10921100 .{ .pinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .long, .sse4_1 },
10931101
1102 .{ .pmaxsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3c }, 0, .none, .sse4_1 },
1103 .{ .pmaxsd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3d }, 0, .none, .sse4_1 },
1104
1105 .{ .pmaxuw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3e }, 0, .none, .sse4_1 },
1106
1107 .{ .pmaxud, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3f }, 0, .none, .sse4_1 },
1108
1109 .{ .pminsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x38 }, 0, .none, .sse4_1 },
1110 .{ .pminsd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x39 }, 0, .none, .sse4_1 },
1111
1112 .{ .pminuw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3a }, 0, .none, .sse4_1 },
1113
1114 .{ .pminud, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3b }, 0, .none, .sse4_1 },
1115
10941116 .{ .pmulld, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .none, .sse4_1 },
10951117
10961118 .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 },
......@@ -1318,6 +1340,24 @@ pub const table = [_]Entry{
13181340
13191341 .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx },
13201342
1343 .{ .vpmaxsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3c }, 0, .vex_128_wig, .avx },
1344 .{ .vpmaxsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xee }, 0, .vex_128_wig, .avx },
1345 .{ .vpmaxsd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3d }, 0, .vex_128_wig, .avx },
1346
1347 .{ .vpmaxub, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xde }, 0, .vex_128_wig, .avx },
1348 .{ .vpmaxuw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3e }, 0, .vex_128_wig, .avx },
1349
1350 .{ .vpmaxud, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3f }, 0, .vex_128_wig, .avx },
1351
1352 .{ .vpminsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x38 }, 0, .vex_128_wig, .avx },
1353 .{ .vpminsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xea }, 0, .vex_128_wig, .avx },
1354 .{ .vpminsd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x39 }, 0, .vex_128_wig, .avx },
1355
1356 .{ .vpminub, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xda }, 0, .vex_128_wig, .avx },
1357 .{ .vpminuw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3a }, 0, .vex_128_wig, .avx },
1358
1359 .{ .vpminud, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3b }, 0, .vex_128_wig, .avx },
1360
13211361 .{ .vpmulhw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .vex_128_wig, .avx },
13221362
13231363 .{ .vpmulld, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .vex_128_wig, .avx },
......@@ -1449,6 +1489,24 @@ pub const table = [_]Entry{
14491489
14501490 .{ .vpandn, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_256_wig, .avx2 },
14511491
1492 .{ .vpmaxsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3c }, 0, .vex_256_wig, .avx },
1493 .{ .vpmaxsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xee }, 0, .vex_256_wig, .avx },
1494 .{ .vpmaxsd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3d }, 0, .vex_256_wig, .avx },
1495
1496 .{ .vpmaxub, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xde }, 0, .vex_256_wig, .avx },
1497 .{ .vpmaxuw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3e }, 0, .vex_256_wig, .avx },
1498
1499 .{ .vpmaxud, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3f }, 0, .vex_256_wig, .avx },
1500
1501 .{ .vpminsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x38 }, 0, .vex_256_wig, .avx },
1502 .{ .vpminsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xea }, 0, .vex_256_wig, .avx },
1503 .{ .vpminsd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x39 }, 0, .vex_256_wig, .avx },
1504
1505 .{ .vpminub, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xda }, 0, .vex_256_wig, .avx },
1506 .{ .vpminuw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3a }, 0, .vex_256_wig, .avx },
1507
1508 .{ .vpminud, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3b }, 0, .vex_256_wig, .avx },
1509
14521510 .{ .vpmulhw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .vex_256_wig, .avx },
14531511
14541512 .{ .vpmulld, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .vex_256_wig, .avx },