authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-09 03:15:27-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 03:07:51-04:00
logc23e80e671686278ea2ea23d164a2c0839ca372c
treede7b522d1daba0f570db582c6b916eb5b29e4308
parent1336619979cfd5145c042ba7e2c6d0fbafc53574

x86_64: implement `@splat`


5 files changed, 270 insertions(+), 9 deletions(-)

src/arch/x86_64/CodeGen.zig+204-4
......@@ -8561,7 +8561,8 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {
85618561 },
85628562 32 => switch (ty.vectorLen()) {
85638563 1 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov },
8564 2...4 => return if (self.hasFeature(.avx))
8564 2 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov },
8565 3...4 => return if (self.hasFeature(.avx))
85658566 if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }
85668567 else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu },
85678568 5...8 => if (self.hasFeature(.avx))
......@@ -8577,6 +8578,14 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {
85778578 return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu },
85788579 else => {},
85798580 },
8581 128 => switch (ty.vectorLen()) {
8582 1 => return if (self.hasFeature(.avx))
8583 if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }
8584 else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu },
8585 2 => if (self.hasFeature(.avx))
8586 return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu },
8587 else => {},
8588 },
85808589 else => {},
85818590 },
85828591 else => {},
......@@ -9939,9 +9948,200 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
99399948
99409949fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
99419950 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9942 _ = ty_op;
9943 return self.fail("TODO implement airSplat for x86_64", .{});
9944 //return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
9951 const vector_ty = self.air.typeOfIndex(inst);
9952 const dst_rc = regClassForType(vector_ty);
9953 const scalar_ty = vector_ty.scalarType();
9954
9955 const src_mcv = try self.resolveInst(ty_op.operand);
9956 const result: MCValue = result: {
9957 switch (scalar_ty.zigTypeTag()) {
9958 else => {},
9959 .Float => switch (scalar_ty.floatBits(self.target.*)) {
9960 32 => switch (vector_ty.vectorLen()) {
9961 1 => {
9962 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
9963 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
9964 try self.genSetReg(dst_reg, scalar_ty, src_mcv);
9965 break :result .{ .register = dst_reg };
9966 },
9967 2...4 => {
9968 if (self.hasFeature(.avx)) {
9969 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
9970 if (src_mcv.isMemory()) try self.asmRegisterMemory(
9971 .{ .v_ss, .broadcast },
9972 dst_reg.to128(),
9973 src_mcv.mem(.dword),
9974 ) else {
9975 const src_reg = if (src_mcv.isRegister())
9976 src_mcv.getReg().?
9977 else
9978 try self.copyToTmpRegister(scalar_ty, src_mcv);
9979 try self.asmRegisterRegisterRegisterImmediate(
9980 .{ .v_ps, .shuf },
9981 dst_reg.to128(),
9982 src_reg.to128(),
9983 src_reg.to128(),
9984 Immediate.u(0),
9985 );
9986 }
9987 break :result .{ .register = dst_reg };
9988 } else {
9989 const dst_mcv = if (src_mcv.isRegister() and
9990 self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
9991 src_mcv
9992 else
9993 try self.copyToRegisterWithInstTracking(inst, scalar_ty, src_mcv);
9994 const dst_reg = dst_mcv.getReg().?;
9995 try self.asmRegisterRegisterImmediate(
9996 .{ ._ps, .shuf },
9997 dst_reg.to128(),
9998 dst_reg.to128(),
9999 Immediate.u(0),
10000 );
10001 break :result dst_mcv;
10002 }
10003 },
10004 5...8 => if (self.hasFeature(.avx)) {
10005 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
10006 if (src_mcv.isMemory()) try self.asmRegisterMemory(
10007 .{ .v_ss, .broadcast },
10008 dst_reg.to256(),
10009 src_mcv.mem(.dword),
10010 ) else {
10011 const src_reg = if (src_mcv.isRegister())
10012 src_mcv.getReg().?
10013 else
10014 try self.copyToTmpRegister(scalar_ty, src_mcv);
10015 if (self.hasFeature(.avx2)) try self.asmRegisterRegister(
10016 .{ .v_ss, .broadcast },
10017 dst_reg.to256(),
10018 src_reg.to128(),
10019 ) else {
10020 try self.asmRegisterRegisterRegisterImmediate(
10021 .{ .v_ps, .shuf },
10022 dst_reg.to128(),
10023 src_reg.to128(),
10024 src_reg.to128(),
10025 Immediate.u(0),
10026 );
10027 try self.asmRegisterRegisterRegisterImmediate(
10028 .{ .v_f128, .insert },
10029 dst_reg.to256(),
10030 dst_reg.to256(),
10031 dst_reg.to128(),
10032 Immediate.u(1),
10033 );
10034 }
10035 }
10036 break :result .{ .register = dst_reg };
10037 },
10038 else => {},
10039 },
10040 64 => switch (vector_ty.vectorLen()) {
10041 1 => {
10042 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
10043 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
10044 try self.genSetReg(dst_reg, scalar_ty, src_mcv);
10045 break :result .{ .register = dst_reg };
10046 },
10047 2 => {
10048 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
10049 if (self.hasFeature(.sse3)) {
10050 if (src_mcv.isMemory()) try self.asmRegisterMemory(
10051 if (self.hasFeature(.avx)) .{ .v_, .movddup } else .{ ._, .movddup },
10052 dst_reg.to128(),
10053 src_mcv.mem(.qword),
10054 ) else try self.asmRegisterRegister(
10055 if (self.hasFeature(.avx)) .{ .v_, .movddup } else .{ ._, .movddup },
10056 dst_reg.to128(),
10057 (if (src_mcv.isRegister())
10058 src_mcv.getReg().?
10059 else
10060 try self.copyToTmpRegister(scalar_ty, src_mcv)).to128(),
10061 );
10062 break :result .{ .register = dst_reg };
10063 } else try self.asmRegisterRegister(
10064 .{ ._ps, .movlh },
10065 dst_reg.to128(),
10066 (if (src_mcv.isRegister())
10067 src_mcv.getReg().?
10068 else
10069 try self.copyToTmpRegister(scalar_ty, src_mcv)).to128(),
10070 );
10071 },
10072 3...4 => if (self.hasFeature(.avx)) {
10073 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
10074 if (src_mcv.isMemory()) try self.asmRegisterMemory(
10075 .{ .v_sd, .broadcast },
10076 dst_reg.to256(),
10077 src_mcv.mem(.qword),
10078 ) else {
10079 const src_reg = if (src_mcv.isRegister())
10080 src_mcv.getReg().?
10081 else
10082 try self.copyToTmpRegister(scalar_ty, src_mcv);
10083 if (self.hasFeature(.avx2)) try self.asmRegisterRegister(
10084 .{ .v_sd, .broadcast },
10085 dst_reg.to256(),
10086 src_reg.to128(),
10087 ) else {
10088 try self.asmRegisterRegister(
10089 .{ .v_, .movddup },
10090 dst_reg.to128(),
10091 src_reg.to128(),
10092 );
10093 try self.asmRegisterRegisterRegisterImmediate(
10094 .{ .v_f128, .insert },
10095 dst_reg.to256(),
10096 dst_reg.to256(),
10097 dst_reg.to128(),
10098 Immediate.u(1),
10099 );
10100 }
10101 }
10102 break :result .{ .register = dst_reg };
10103 },
10104 else => {},
10105 },
10106 128 => switch (vector_ty.vectorLen()) {
10107 1 => {
10108 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
10109 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
10110 try self.genSetReg(dst_reg, scalar_ty, src_mcv);
10111 break :result .{ .register = dst_reg };
10112 },
10113 2 => if (self.hasFeature(.avx)) {
10114 const dst_reg = try self.register_manager.allocReg(inst, dst_rc);
10115 if (src_mcv.isMemory()) try self.asmRegisterMemory(
10116 .{ .v_f128, .broadcast },
10117 dst_reg.to256(),
10118 src_mcv.mem(.xword),
10119 ) else {
10120 const src_reg = if (src_mcv.isRegister())
10121 src_mcv.getReg().?
10122 else
10123 try self.copyToTmpRegister(scalar_ty, src_mcv);
10124 try self.asmRegisterRegisterRegisterImmediate(
10125 .{ .v_f128, .insert },
10126 dst_reg.to256(),
10127 src_reg.to256(),
10128 src_reg.to128(),
10129 Immediate.u(1),
10130 );
10131 }
10132 break :result .{ .register = dst_reg };
10133 },
10134 else => {},
10135 },
10136 16, 80 => {},
10137 else => unreachable,
10138 },
10139 }
10140 return self.fail("TODO implement airSplat for {}", .{
10141 vector_ty.fmt(self.bin_file.options.module.?),
10142 });
10143 };
10144 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
994510145}
994610146
994710147fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
src/arch/x86_64/Encoding.zig+11-2
......@@ -270,10 +270,12 @@ pub const Mnemonic = enum {
270270 divps, divss,
271271 maxps, maxss,
272272 minps, minss,
273 movaps, movhlps, movss, movups,
273 movaps, movhlps, movlhps,
274 movss, movups,
274275 mulps, mulss,
275276 orps,
276277 pextrw, pinsrw,
278 shufps,
277279 sqrtps, sqrtss,
278280 subps, subss,
279281 ucomiss,
......@@ -296,6 +298,7 @@ pub const Mnemonic = enum {
296298 psrld, psrlq, psrlw,
297299 punpckhbw, punpckhdq, punpckhqdq, punpckhwd,
298300 punpcklbw, punpckldq, punpcklqdq, punpcklwd,
301 shufpd,
299302 sqrtpd, sqrtsd,
300303 subpd, subsd,
301304 ucomisd,
......@@ -303,17 +306,22 @@ pub const Mnemonic = enum {
303306 // SSE3
304307 movddup, movshdup, movsldup,
305308 // SSE4.1
309 extractps,
310 insertps,
306311 pextrb, pextrd, pextrq,
307312 pinsrb, pinsrd, pinsrq,
308313 roundpd, roundps, roundsd, roundss,
309314 // AVX
310315 vaddpd, vaddps, vaddsd, vaddss,
316 vbroadcastf128, vbroadcastsd, vbroadcastss,
311317 vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd,
312318 vdivpd, vdivps, vdivsd, vdivss,
319 vextractf128, vextractps,
320 vinsertf128, vinsertps,
313321 vmaxpd, vmaxps, vmaxsd, vmaxss,
314322 vminpd, vminps, vminsd, vminss,
315323 vmovapd, vmovaps,
316 vmovddup, vmovhlps,
324 vmovddup, vmovhlps, vmovlhps,
317325 vmovsd,
318326 vmovshdup, vmovsldup,
319327 vmovss,
......@@ -326,6 +334,7 @@ pub const Mnemonic = enum {
326334 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,
327335 vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd,
328336 vroundpd, vroundps, vroundsd, vroundss,
337 vshufpd, vshufps,
329338 vsqrtpd, vsqrtps, vsqrtsd, vsqrtss,
330339 vsubpd, vsubps, vsubsd, vsubss,
331340 // F16C
src/arch/x86_64/Lower.zig+2
......@@ -300,6 +300,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
300300 else
301301 .none,
302302 }, mnemonic: {
303 @setEvalBranchQuota(2_000);
304
303305 comptime var max_len = 0;
304306 inline for (@typeInfo(Mnemonic).Enum.fields) |field| max_len = @max(field.name.len, max_len);
305307 var buf: [max_len]u8 = undefined;
src/arch/x86_64/Mir.zig+15
......@@ -256,6 +256,8 @@ pub const Inst = struct {
256256 v_sd,
257257 /// VEX-Encoded ___ Packed Double-Precision Values
258258 v_pd,
259 /// VEX-Encoded ___ 128-Bits Of Floating-Point Data
260 v_f128,
259261
260262 /// Mask ___ Byte
261263 k_b,
......@@ -454,6 +456,8 @@ pub const Inst = struct {
454456 mova,
455457 /// Move packed single-precision floating-point values high to low
456458 movhl,
459 /// Move packed single-precision floating-point values low to high
460 movlh,
457461 /// Move unaligned packed single-precision floating-point values
458462 /// Move unaligned packed double-precision floating-point values
459463 movu,
......@@ -488,6 +492,9 @@ pub const Inst = struct {
488492 cvtsi2sd,
489493 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value
490494 cvtss2sd,
495 /// Packed interleave shuffle of quadruplets of single-precision floating-point values
496 /// Packed interleave shuffle of pairs of double-precision floating-point values
497 shuf,
491498 /// Shuffle packed high words
492499 shufh,
493500 /// Shuffle packed low words
......@@ -520,12 +527,20 @@ pub const Inst = struct {
520527 /// Replicate single floating-point values
521528 movsldup,
522529
530 /// Extract packed floating-point values
531 extract,
532 /// Insert scalar single-precision floating-point value
533 /// Insert packed floating-point values
534 insert,
523535 /// Round packed single-precision floating-point values
524536 /// Round scalar single-precision floating-point value
525537 /// Round packed double-precision floating-point values
526538 /// Round scalar double-precision floating-point value
527539 round,
528540
541 /// Load with broadcast floating-point data
542 broadcast,
543
529544 /// Convert 16-bit floating-point values to single-precision floating-point values
530545 cvtph2ps,
531546 /// Convert single-precision floating-point values to 16-bit floating-point values
src/arch/x86_64/encodings.zig+38-3
......@@ -867,6 +867,8 @@ pub const table = [_]Entry{
867867
868868 .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse },
869869
870 .{ .movlhps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x16 }, 0, .none, .sse },
871
870872 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse },
871873 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse },
872874
......@@ -879,14 +881,16 @@ pub const table = [_]Entry{
879881
880882 .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse },
881883
882 .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse },
883
884 .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse },
884 .{ .shufps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .none, .sse },
885885
886886 .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse },
887887
888888 .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse },
889889
890 .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse },
891
892 .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse },
893
890894 .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .none, .sse },
891895
892896 .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse },
......@@ -967,6 +971,8 @@ pub const table = [_]Entry{
967971 .{ .punpckldq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .none, .sse2 },
968972 .{ .punpcklqdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .none, .sse2 },
969973
974 .{ .shufpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0xc6 }, 0, .none, .sse2 },
975
970976 .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .none, .sse2 },
971977
972978 .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 },
......@@ -990,6 +996,10 @@ pub const table = [_]Entry{
990996 .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 },
991997
992998 // SSE4.1
999 .{ .extractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .none, .sse4_1 },
1000
1001 .{ .insertps, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .none, .sse4_1 },
1002
9931003 .{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 },
9941004 .{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 },
9951005 .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 },
......@@ -1019,6 +1029,11 @@ pub const table = [_]Entry{
10191029
10201030 .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx },
10211031
1032 .{ .vbroadcastss, .rm, &.{ .xmm, .m32 }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx },
1033 .{ .vbroadcastss, .rm, &.{ .ymm, .m32 }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx },
1034 .{ .vbroadcastsd, .rm, &.{ .ymm, .m64 }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx },
1035 .{ .vbroadcastf128, .rm, &.{ .ymm, .m128 }, &.{ 0x66, 0x0f, 0x38, 0x1a }, 0, .vex_256_w0, .avx },
1036
10221037 .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },
10231038
10241039 .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx },
......@@ -1039,6 +1054,14 @@ pub const table = [_]Entry{
10391054
10401055 .{ .vdivss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .vex_lig_wig, .avx },
10411056
1057 .{ .vextractf128, .mri, &.{ .xmm_m128, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x19 }, 0, .vex_256_w0, .avx },
1058
1059 .{ .vextractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .vex_128_wig, .avx },
1060
1061 .{ .vinsertf128, .rvmi, &.{ .ymm, .ymm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x18 }, 0, .vex_256_w0, .avx },
1062
1063 .{ .vinsertps, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .vex_128_wig, .avx },
1064
10421065 .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx },
10431066 .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx },
10441067
......@@ -1074,6 +1097,8 @@ pub const table = [_]Entry{
10741097
10751098 .{ .vmovhlps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .vex_128_wig, .avx },
10761099
1100 .{ .vmovlhps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x16 }, 0, .vex_128_wig, .avx },
1101
10771102 .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },
10781103 .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },
10791104 .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx },
......@@ -1150,6 +1175,12 @@ pub const table = [_]Entry{
11501175
11511176 .{ .vroundss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .vex_lig_wig, .avx },
11521177
1178 .{ .vshufpd, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0xc6 }, 0, .vex_128_wig, .avx },
1179 .{ .vshufpd, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0xc6 }, 0, .vex_256_wig, .avx },
1180
1181 .{ .vshufps, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .vex_128_wig, .avx },
1182 .{ .vshufps, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .vex_256_wig, .avx },
1183
11531184 .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx },
11541185 .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx },
11551186
......@@ -1201,6 +1232,10 @@ pub const table = [_]Entry{
12011232 .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma },
12021233
12031234 // AVX2
1235 .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 },
1236 .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 },
1237 .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 },
1238
12041239 .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 },
12051240 .{ .vpsrlw, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_256_wig, .avx2 },
12061241 .{ .vpsrld, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_256_wig, .avx2 },