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 {...@@ -8561,7 +8561,8 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {
8561 },8561 },
8562 32 => switch (ty.vectorLen()) {8562 32 => switch (ty.vectorLen()) {
8563 1 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov },8563 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))
8565 if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }8566 if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }
8566 else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu },8567 else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu },
8567 5...8 => if (self.hasFeature(.avx))8568 5...8 => if (self.hasFeature(.avx))
...@@ -8577,6 +8578,14 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {...@@ -8577,6 +8578,14 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {
8577 return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu },8578 return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu },
8578 else => {},8579 else => {},
8579 },8580 },
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 },
8580 else => {},8589 else => {},
8581 },8590 },
8582 else => {},8591 else => {},
...@@ -9939,9 +9948,200 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -9939,9 +9948,200 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
99399948
9940fn airSplat(self: *Self, inst: Air.Inst.Index) !void {9949fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
9941 const ty_op = self.air.instructions.items(.data)[inst].ty_op;9950 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9942 _ = ty_op;9951 const vector_ty = self.air.typeOfIndex(inst);
9943 return self.fail("TODO implement airSplat for x86_64", .{});9952 const dst_rc = regClassForType(vector_ty);
9944 //return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });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 });
9945}10145}
994610146
9947fn airSelect(self: *Self, inst: Air.Inst.Index) !void {10147fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
src/arch/x86_64/Encoding.zig+11-2
...@@ -270,10 +270,12 @@ pub const Mnemonic = enum {...@@ -270,10 +270,12 @@ pub const Mnemonic = enum {
270 divps, divss,270 divps, divss,
271 maxps, maxss,271 maxps, maxss,
272 minps, minss,272 minps, minss,
273 movaps, movhlps, movss, movups,273 movaps, movhlps, movlhps,
274 movss, movups,
274 mulps, mulss,275 mulps, mulss,
275 orps,276 orps,
276 pextrw, pinsrw,277 pextrw, pinsrw,
278 shufps,
277 sqrtps, sqrtss,279 sqrtps, sqrtss,
278 subps, subss,280 subps, subss,
279 ucomiss,281 ucomiss,
...@@ -296,6 +298,7 @@ pub const Mnemonic = enum {...@@ -296,6 +298,7 @@ pub const Mnemonic = enum {
296 psrld, psrlq, psrlw,298 psrld, psrlq, psrlw,
297 punpckhbw, punpckhdq, punpckhqdq, punpckhwd,299 punpckhbw, punpckhdq, punpckhqdq, punpckhwd,
298 punpcklbw, punpckldq, punpcklqdq, punpcklwd,300 punpcklbw, punpckldq, punpcklqdq, punpcklwd,
301 shufpd,
299 sqrtpd, sqrtsd,302 sqrtpd, sqrtsd,
300 subpd, subsd,303 subpd, subsd,
301 ucomisd,304 ucomisd,
...@@ -303,17 +306,22 @@ pub const Mnemonic = enum {...@@ -303,17 +306,22 @@ pub const Mnemonic = enum {
303 // SSE3306 // SSE3
304 movddup, movshdup, movsldup,307 movddup, movshdup, movsldup,
305 // SSE4.1308 // SSE4.1
309 extractps,
310 insertps,
306 pextrb, pextrd, pextrq,311 pextrb, pextrd, pextrq,
307 pinsrb, pinsrd, pinsrq,312 pinsrb, pinsrd, pinsrq,
308 roundpd, roundps, roundsd, roundss,313 roundpd, roundps, roundsd, roundss,
309 // AVX314 // AVX
310 vaddpd, vaddps, vaddsd, vaddss,315 vaddpd, vaddps, vaddsd, vaddss,
316 vbroadcastf128, vbroadcastsd, vbroadcastss,
311 vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd,317 vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd,
312 vdivpd, vdivps, vdivsd, vdivss,318 vdivpd, vdivps, vdivsd, vdivss,
319 vextractf128, vextractps,
320 vinsertf128, vinsertps,
313 vmaxpd, vmaxps, vmaxsd, vmaxss,321 vmaxpd, vmaxps, vmaxsd, vmaxss,
314 vminpd, vminps, vminsd, vminss,322 vminpd, vminps, vminsd, vminss,
315 vmovapd, vmovaps,323 vmovapd, vmovaps,
316 vmovddup, vmovhlps,324 vmovddup, vmovhlps, vmovlhps,
317 vmovsd,325 vmovsd,
318 vmovshdup, vmovsldup,326 vmovshdup, vmovsldup,
319 vmovss,327 vmovss,
...@@ -326,6 +334,7 @@ pub const Mnemonic = enum {...@@ -326,6 +334,7 @@ pub const Mnemonic = enum {
326 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,334 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,
327 vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd,335 vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd,
328 vroundpd, vroundps, vroundsd, vroundss,336 vroundpd, vroundps, vroundsd, vroundss,
337 vshufpd, vshufps,
329 vsqrtpd, vsqrtps, vsqrtsd, vsqrtss,338 vsqrtpd, vsqrtps, vsqrtsd, vsqrtss,
330 vsubpd, vsubps, vsubsd, vsubss,339 vsubpd, vsubps, vsubsd, vsubss,
331 // F16C340 // F16C
src/arch/x86_64/Lower.zig+2
...@@ -300,6 +300,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -300,6 +300,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
300 else300 else
301 .none,301 .none,
302 }, mnemonic: {302 }, mnemonic: {
303 @setEvalBranchQuota(2_000);
304
303 comptime var max_len = 0;305 comptime var max_len = 0;
304 inline for (@typeInfo(Mnemonic).Enum.fields) |field| max_len = @max(field.name.len, max_len);306 inline for (@typeInfo(Mnemonic).Enum.fields) |field| max_len = @max(field.name.len, max_len);
305 var buf: [max_len]u8 = undefined;307 var buf: [max_len]u8 = undefined;
src/arch/x86_64/Mir.zig+15
...@@ -256,6 +256,8 @@ pub const Inst = struct {...@@ -256,6 +256,8 @@ pub const Inst = struct {
256 v_sd,256 v_sd,
257 /// VEX-Encoded ___ Packed Double-Precision Values257 /// VEX-Encoded ___ Packed Double-Precision Values
258 v_pd,258 v_pd,
259 /// VEX-Encoded ___ 128-Bits Of Floating-Point Data
260 v_f128,
259261
260 /// Mask ___ Byte262 /// Mask ___ Byte
261 k_b,263 k_b,
...@@ -454,6 +456,8 @@ pub const Inst = struct {...@@ -454,6 +456,8 @@ pub const Inst = struct {
454 mova,456 mova,
455 /// Move packed single-precision floating-point values high to low457 /// Move packed single-precision floating-point values high to low
456 movhl,458 movhl,
459 /// Move packed single-precision floating-point values low to high
460 movlh,
457 /// Move unaligned packed single-precision floating-point values461 /// Move unaligned packed single-precision floating-point values
458 /// Move unaligned packed double-precision floating-point values462 /// Move unaligned packed double-precision floating-point values
459 movu,463 movu,
...@@ -488,6 +492,9 @@ pub const Inst = struct {...@@ -488,6 +492,9 @@ pub const Inst = struct {
488 cvtsi2sd,492 cvtsi2sd,
489 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value493 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value
490 cvtss2sd,494 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,
491 /// Shuffle packed high words498 /// Shuffle packed high words
492 shufh,499 shufh,
493 /// Shuffle packed low words500 /// Shuffle packed low words
...@@ -520,12 +527,20 @@ pub const Inst = struct {...@@ -520,12 +527,20 @@ pub const Inst = struct {
520 /// Replicate single floating-point values527 /// Replicate single floating-point values
521 movsldup,528 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,
523 /// Round packed single-precision floating-point values535 /// Round packed single-precision floating-point values
524 /// Round scalar single-precision floating-point value536 /// Round scalar single-precision floating-point value
525 /// Round packed double-precision floating-point values537 /// Round packed double-precision floating-point values
526 /// Round scalar double-precision floating-point value538 /// Round scalar double-precision floating-point value
527 round,539 round,
528540
541 /// Load with broadcast floating-point data
542 broadcast,
543
529 /// Convert 16-bit floating-point values to single-precision floating-point values544 /// Convert 16-bit floating-point values to single-precision floating-point values
530 cvtph2ps,545 cvtph2ps,
531 /// Convert single-precision floating-point values to 16-bit floating-point values546 /// 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{...@@ -867,6 +867,8 @@ pub const table = [_]Entry{
867867
868 .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse },868 .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse },
869869
870 .{ .movlhps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x16 }, 0, .none, .sse },
871
870 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse },872 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse },
871 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse },873 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse },
872874
...@@ -879,14 +881,16 @@ pub const table = [_]Entry{...@@ -879,14 +881,16 @@ pub const table = [_]Entry{
879881
880 .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse },882 .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse },
881883
882 .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse },884 .{ .shufps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .none, .sse },
883
884 .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse },
885885
886 .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse },886 .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse },
887887
888 .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse },888 .{ .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
890 .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .none, .sse },894 .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .none, .sse },
891895
892 .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse },896 .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse },
...@@ -967,6 +971,8 @@ pub const table = [_]Entry{...@@ -967,6 +971,8 @@ pub const table = [_]Entry{
967 .{ .punpckldq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .none, .sse2 },971 .{ .punpckldq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .none, .sse2 },
968 .{ .punpcklqdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .none, .sse2 },972 .{ .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
970 .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .none, .sse2 },976 .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .none, .sse2 },
971977
972 .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 },978 .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 },
...@@ -990,6 +996,10 @@ pub const table = [_]Entry{...@@ -990,6 +996,10 @@ pub const table = [_]Entry{
990 .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 },996 .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 },
991997
992 // SSE4.1998 // 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
993 .{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 },1003 .{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 },
994 .{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 },1004 .{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 },
995 .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 },1005 .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 },
...@@ -1019,6 +1029,11 @@ pub const table = [_]Entry{...@@ -1019,6 +1029,11 @@ pub const table = [_]Entry{
10191029
1020 .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx },1030 .{ .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
1022 .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },1037 .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },
10231038
1024 .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx },1039 .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx },
...@@ -1039,6 +1054,14 @@ pub const table = [_]Entry{...@@ -1039,6 +1054,14 @@ pub const table = [_]Entry{
10391054
1040 .{ .vdivss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .vex_lig_wig, .avx },1055 .{ .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
1042 .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx },1065 .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx },
1043 .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx },1066 .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx },
10441067
...@@ -1074,6 +1097,8 @@ pub const table = [_]Entry{...@@ -1074,6 +1097,8 @@ pub const table = [_]Entry{
10741097
1075 .{ .vmovhlps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .vex_128_wig, .avx },1098 .{ .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
1077 .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },1102 .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },
1078 .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },1103 .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx },
1079 .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx },1104 .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx },
...@@ -1150,6 +1175,12 @@ pub const table = [_]Entry{...@@ -1150,6 +1175,12 @@ pub const table = [_]Entry{
11501175
1151 .{ .vroundss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .vex_lig_wig, .avx },1176 .{ .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
1153 .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx },1184 .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx },
1154 .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx },1185 .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx },
11551186
...@@ -1201,6 +1232,10 @@ pub const table = [_]Entry{...@@ -1201,6 +1232,10 @@ pub const table = [_]Entry{
1201 .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma },1232 .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma },
12021233
1203 // AVX21234 // 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
1204 .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 },1239 .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 },
1205 .{ .vpsrlw, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_256_wig, .avx2 },1240 .{ .vpsrlw, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_256_wig, .avx2 },
1206 .{ .vpsrld, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_256_wig, .avx2 },1241 .{ .vpsrld, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_256_wig, .avx2 },