authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 00:26:30-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 03:07:51-04:00
logbd771bec49fbb7845ad2635c0dd13aa971a81fee
tree37eb56b0e97eb82e0e13e09ba14adc0ec3ec1cf0
parent42d9789f46e94e17d8ab8d02f356eaaa44fb2822

x86_64: implement integer vector add/sub


4 files changed, 160 insertions(+), 6 deletions(-)

src/arch/x86_64/CodeGen.zig+75-5
......@@ -6520,6 +6520,57 @@ fn genBinOp(
65206520 },
65216521 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
65226522 else => null,
6523 .Int => switch (lhs_ty.childType().intInfo(self.target.*).bits) {
6524 8 => switch (lhs_ty.vectorLen()) {
6525 1...16 => switch (air_tag) {
6526 .add,
6527 .addwrap,
6528 => if (self.hasFeature(.avx)) .{ .vp_b, .add } else .{ .p_b, .add },
6529 .sub,
6530 .subwrap,
6531 => if (self.hasFeature(.avx)) .{ .vp_b, .sub } else .{ .p_b, .sub },
6532 else => null,
6533 },
6534 else => null,
6535 },
6536 16 => switch (lhs_ty.vectorLen()) {
6537 1...8 => switch (air_tag) {
6538 .add,
6539 .addwrap,
6540 => if (self.hasFeature(.avx)) .{ .vp_w, .add } else .{ .p_w, .add },
6541 .sub,
6542 .subwrap,
6543 => if (self.hasFeature(.avx)) .{ .vp_w, .sub } else .{ .p_w, .sub },
6544 else => null,
6545 },
6546 else => null,
6547 },
6548 32 => switch (lhs_ty.vectorLen()) {
6549 1...4 => switch (air_tag) {
6550 .add,
6551 .addwrap,
6552 => if (self.hasFeature(.avx)) .{ .vp_d, .add } else .{ .p_d, .add },
6553 .sub,
6554 .subwrap,
6555 => if (self.hasFeature(.avx)) .{ .vp_d, .sub } else .{ .p_d, .sub },
6556 else => null,
6557 },
6558 else => null,
6559 },
6560 64 => switch (lhs_ty.vectorLen()) {
6561 1...2 => switch (air_tag) {
6562 .add,
6563 .addwrap,
6564 => if (self.hasFeature(.avx)) .{ .vp_q, .add } else .{ .p_q, .add },
6565 .sub,
6566 .subwrap,
6567 => if (self.hasFeature(.avx)) .{ .vp_q, .sub } else .{ .p_q, .sub },
6568 else => null,
6569 },
6570 else => null,
6571 },
6572 else => null,
6573 },
65236574 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
65246575 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen()) {
65256576 1 => {
......@@ -6812,7 +6863,7 @@ fn genBinOp(
68126863 );
68136864 }
68146865 switch (air_tag) {
6815 .add, .sub, .mul, .div_float, .div_exact => {},
6866 .add, .addwrap, .sub, .subwrap, .mul, .mulwrap, .div_float, .div_exact => {},
68166867 .div_trunc, .div_floor => try self.genRound(
68176868 lhs_ty,
68186869 dst_reg,
......@@ -9043,14 +9094,33 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
90439094 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
90449095 ),
90459096 .sse => try self.asmRegisterRegister(
9046 switch (ty.scalarType().zigTypeTag()) {
9047 else => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else .{ ._, .movdqa },
9097 if (@as(?Mir.Inst.FixedTag, switch (ty.scalarType().zigTypeTag()) {
9098 else => switch (abi_size) {
9099 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
9100 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },
9101 9...16 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else .{ ._, .movdqa },
9102 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null,
9103 else => null,
9104 },
90489105 .Float => switch (ty.floatBits(self.target.*)) {
9049 else => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else .{ ._, .movdqa },
9106 16, 128 => switch (abi_size) {
9107 2...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
9108 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },
9109 9...16 => if (self.hasFeature(.avx))
9110 .{ .v_, .movdqa }
9111 else
9112 .{ ._, .movdqa },
9113 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null,
9114 else => null,
9115 },
90509116 32 => if (self.hasFeature(.avx)) .{ .v_ps, .mova } else .{ ._ps, .mova },
90519117 64 => if (self.hasFeature(.avx)) .{ .v_pd, .mova } else .{ ._pd, .mova },
9118 80 => null,
9119 else => unreachable,
90529120 },
9053 },
9121 })) |tag| tag else return self.fail("TODO implement genSetReg for {}", .{
9122 ty.fmt(self.bin_file.options.module.?),
9123 }),
90549124 registerAlias(dst_reg, abi_size),
90559125 registerAlias(src_reg, abi_size),
90569126 ),
src/arch/x86_64/Encoding.zig+5-1
......@@ -262,7 +262,9 @@ pub const Mnemonic = enum {
262262 fisttp, fld,
263263 // MMX
264264 movd, movq,
265 paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw,
265266 pand, pandn, por, pxor,
267 psubb, psubd, psubq, psubsb, psubsw, psubusb, psubusw, psubw,
266268 // SSE
267269 addps, addss,
268270 andps,
......@@ -341,12 +343,14 @@ pub const Mnemonic = enum {
341343 vmovupd, vmovups,
342344 vmulpd, vmulps, vmulsd, vmulss,
343345 vorpd, vorps,
346 vpaddb, vpaddd, vpaddq, vpaddsb, vpaddsw, vpaddusb, vpaddusw, vpaddw,
344347 vpand, vpandn,
345348 vpextrb, vpextrd, vpextrq, vpextrw,
346349 vpinsrb, vpinsrd, vpinsrq, vpinsrw,
347350 vpor,
348351 vpshufhw, vpshuflw,
349352 vpsrld, vpsrlq, vpsrlw,
353 vpsubb, vpsubd, vpsubq, vpsubsb, vpsubsw, vpsubusb, vpsubusw, vpsubw,
350354 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,
351355 vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd,
352356 vpxor,
......@@ -746,7 +750,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op
746750}
747751
748752const mnemonic_to_encodings_map = init: {
749 @setEvalBranchQuota(25_000);
753 @setEvalBranchQuota(30_000);
750754 const encodings = @import("encodings.zig");
751755 var entries = encodings.table;
752756 std.sort.sort(encodings.Entry, &entries, {}, struct {
src/arch/x86_64/Mir.zig+11
......@@ -288,6 +288,7 @@ pub const Inst = struct {
288288 /// Add with carry
289289 adc,
290290 /// Add
291 /// Add packed integers
291292 /// Add packed single-precision floating-point values
292293 /// Add scalar single-precision floating-point values
293294 /// Add packed double-precision floating-point values
......@@ -420,6 +421,7 @@ pub const Inst = struct {
420421 /// Double precision shift right
421422 sh,
422423 /// Subtract
424 /// Subtract packed integers
423425 /// Subtract packed single-precision floating-point values
424426 /// Subtract scalar single-precision floating-point values
425427 /// Subtract packed double-precision floating-point values
......@@ -444,9 +446,18 @@ pub const Inst = struct {
444446 /// Bitwise logical xor of packed double-precision floating-point values
445447 xor,
446448
449 /// Add packed signed integers with signed saturation
450 adds,
451 /// Add packed unsigned integers with unsigned saturation
452 addus,
447453 /// Bitwise logical and not of packed single-precision floating-point values
448454 /// Bitwise logical and not of packed double-precision floating-point values
449455 andn,
456 /// Subtract packed signed integers with signed saturation
457 subs,
458 /// Subtract packed unsigned integers with unsigned saturation
459 subus,
460
450461 /// Convert packed doubleword integers to packed single-precision floating-point values
451462 /// Convert packed doubleword integers to packed double-precision floating-point values
452463 cvtpi2,
src/arch/x86_64/encodings.zig+69
......@@ -992,6 +992,17 @@ pub const table = [_]Entry{
992992
993993 .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 },
994994
995 .{ .paddb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfc }, 0, .none, .sse2 },
996 .{ .paddw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfd }, 0, .none, .sse2 },
997 .{ .paddd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfe }, 0, .none, .sse2 },
998 .{ .paddq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd4 }, 0, .none, .sse2 },
999
1000 .{ .paddsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xec }, 0, .none, .sse2 },
1001 .{ .paddsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xed }, 0, .none, .sse2 },
1002
1003 .{ .paddusb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdc }, 0, .none, .sse2 },
1004 .{ .paddusw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdd }, 0, .none, .sse2 },
1005
9951006 .{ .pand, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdb }, 0, .none, .sse2 },
9961007
9971008 .{ .pandn, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdf }, 0, .none, .sse2 },
......@@ -1013,6 +1024,18 @@ pub const table = [_]Entry{
10131024 .{ .psrlq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .none, .sse2 },
10141025 .{ .psrlq, .mi, &.{ .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .none, .sse2 },
10151026
1027 .{ .psubb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf8 }, 0, .none, .sse2 },
1028 .{ .psubw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf9 }, 0, .none, .sse2 },
1029 .{ .psubd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfa }, 0, .none, .sse2 },
1030
1031 .{ .psubsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe8 }, 0, .none, .sse2 },
1032 .{ .psubsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe9 }, 0, .none, .sse2 },
1033
1034 .{ .psubq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfb }, 0, .none, .sse2 },
1035
1036 .{ .psubusb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd8 }, 0, .none, .sse2 },
1037 .{ .psubusw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd9 }, 0, .none, .sse2 },
1038
10161039 .{ .punpckhbw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x68 }, 0, .none, .sse2 },
10171040 .{ .punpckhwd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x69 }, 0, .none, .sse2 },
10181041 .{ .punpckhdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6a }, 0, .none, .sse2 },
......@@ -1261,6 +1284,17 @@ pub const table = [_]Entry{
12611284 .{ .vorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .vex_128_wig, .avx },
12621285 .{ .vorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x56 }, 0, .vex_256_wig, .avx },
12631286
1287 .{ .vpaddb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_128_wig, .avx },
1288 .{ .vpaddw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_128_wig, .avx },
1289 .{ .vpaddd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfe }, 0, .vex_128_wig, .avx },
1290 .{ .vpaddq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd4 }, 0, .vex_128_wig, .avx },
1291
1292 .{ .vpaddsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xec }, 0, .vex_128_wig, .avx },
1293 .{ .vpaddsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xed }, 0, .vex_128_wig, .avx },
1294
1295 .{ .vpaddusb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdc }, 0, .vex_128_wig, .avx },
1296 .{ .vpaddusw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdd }, 0, .vex_128_wig, .avx },
1297
12641298 .{ .vpand, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdb }, 0, .vex_128_wig, .avx },
12651299
12661300 .{ .vpandn, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_128_wig, .avx },
......@@ -1287,6 +1321,18 @@ pub const table = [_]Entry{
12871321 .{ .vpsrlq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .vex_128_wig, .avx },
12881322 .{ .vpsrlq, .vmi, &.{ .xmm, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .vex_128_wig, .avx },
12891323
1324 .{ .vpsubb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf8 }, 0, .vex_128_wig, .avx },
1325 .{ .vpsubw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf9 }, 0, .vex_128_wig, .avx },
1326 .{ .vpsubd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfa }, 0, .vex_128_wig, .avx },
1327
1328 .{ .vpsubsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe8 }, 0, .vex_128_wig, .avx },
1329 .{ .vpsubsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe9 }, 0, .vex_128_wig, .avx },
1330
1331 .{ .vpsubq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfb }, 0, .vex_128_wig, .avx },
1332
1333 .{ .vpsubusb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd8 }, 0, .vex_128_wig, .avx },
1334 .{ .vpsubusw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd9 }, 0, .vex_128_wig, .avx },
1335
12901336 .{ .vpunpckhbw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x68 }, 0, .vex_128_wig, .avx },
12911337 .{ .vpunpckhwd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x69 }, 0, .vex_128_wig, .avx },
12921338 .{ .vpunpckhdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6a }, 0, .vex_128_wig, .avx },
......@@ -1376,6 +1422,17 @@ pub const table = [_]Entry{
13761422 .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 },
13771423 .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 },
13781424
1425 .{ .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 },
1427 .{ .vpaddd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfe }, 0, .vex_256_wig, .avx2 },
1428 .{ .vpaddq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd4 }, 0, .vex_256_wig, .avx2 },
1429
1430 .{ .vpaddsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xec }, 0, .vex_256_wig, .avx2 },
1431 .{ .vpaddsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xed }, 0, .vex_256_wig, .avx2 },
1432
1433 .{ .vpaddusb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdc }, 0, .vex_256_wig, .avx2 },
1434 .{ .vpaddusw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdd }, 0, .vex_256_wig, .avx2 },
1435
13791436 .{ .vpand, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdb }, 0, .vex_256_wig, .avx2 },
13801437
13811438 .{ .vpandn, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_256_wig, .avx2 },
......@@ -1389,6 +1446,18 @@ pub const table = [_]Entry{
13891446 .{ .vpsrlq, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .vex_256_wig, .avx2 },
13901447 .{ .vpsrlq, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .vex_256_wig, .avx2 },
13911448
1449 .{ .vpsubb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xf8 }, 0, .vex_256_wig, .avx2 },
1450 .{ .vpsubw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xf9 }, 0, .vex_256_wig, .avx2 },
1451 .{ .vpsubd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfa }, 0, .vex_256_wig, .avx2 },
1452
1453 .{ .vpsubsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe8 }, 0, .vex_256_wig, .avx2 },
1454 .{ .vpsubsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe9 }, 0, .vex_256_wig, .avx2 },
1455
1456 .{ .vpsubq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfb }, 0, .vex_256_wig, .avx2 },
1457
1458 .{ .vpsubusb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd8 }, 0, .vex_256_wig, .avx2 },
1459 .{ .vpsubusw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd9 }, 0, .vex_256_wig, .avx2 },
1460
13921461 .{ .vpunpckhbw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x68 }, 0, .vex_256_wig, .avx2 },
13931462 .{ .vpunpckhwd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x69 }, 0, .vex_256_wig, .avx2 },
13941463 .{ .vpunpckhdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6a }, 0, .vex_256_wig, .avx2 },