authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-07 09:06:12-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-08 07:36:20-04:00
log057139fda575e0e6038b821256a45669cd70a073
tree38b4efefb2f63fdb4a6c369caf38d025810d3dd9
parentea957c4cff77f045108863cb5552b3511cb455c1

x86_64: implement binary operations for float vectors


5 files changed, 651 insertions(+), 290 deletions(-)

src/arch/x86_64/CodeGen.zig+377-265
...@@ -1176,6 +1176,21 @@ fn asmRegisterRegisterRegister(...@@ -1176,6 +1176,21 @@ fn asmRegisterRegisterRegister(
1176 });1176 });
1177}1177}
11781178
1179fn asmRegisterRegisterRegisterImmediate(
1180 self: *Self,
1181 tag: Mir.Inst.Tag,
1182 reg1: Register,
1183 reg2: Register,
1184 reg3: Register,
1185 imm: Immediate,
1186) !void {
1187 _ = try self.addInst(.{
1188 .tag = tag,
1189 .ops = .rrri,
1190 .data = .{ .rrri = .{ .r1 = reg1, .r2 = reg2, .r3 = reg3, .i = @intCast(u8, imm.unsigned) } },
1191 });
1192}
1193
1179fn asmRegisterRegisterImmediate(1194fn asmRegisterRegisterImmediate(
1180 self: *Self,1195 self: *Self,
1181 tag: Mir.Inst.Tag,1196 tag: Mir.Inst.Tag,
...@@ -2310,20 +2325,31 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2310,20 +2325,31 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
2310 }),2325 }),
2311 }2326 }
2312 } else if (src_bits == 64 and dst_bits == 32) {2327 } else if (src_bits == 64 and dst_bits == 32) {
2313 if (self.hasFeature(.avx)) if (src_mcv.isRegister()) try self.asmRegisterRegisterRegister(2328 if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
2314 .vcvtsd2ss,2329 .vcvtsd2ss,
2315 dst_reg,2330 dst_reg,
2316 dst_reg,2331 dst_reg,
2317 src_mcv.getReg().?.to128(),2332 src_mcv.mem(.qword),
2318 ) else try self.asmRegisterRegisterMemory(2333 ) else try self.asmRegisterRegisterRegister(
2319 .vcvtsd2ss,2334 .vcvtsd2ss,
2320 dst_reg,2335 dst_reg,
2321 dst_reg,2336 dst_reg,
2337 (if (src_mcv.isRegister())
2338 src_mcv.getReg().?
2339 else
2340 try self.copyToTmpRegister(src_ty, src_mcv)).to128(),
2341 ) else if (src_mcv.isMemory()) try self.asmRegisterMemory(
2342 .cvtsd2ss,
2343 dst_reg,
2322 src_mcv.mem(.qword),2344 src_mcv.mem(.qword),
2323 ) else if (src_mcv.isRegister())2345 ) else try self.asmRegisterRegister(
2324 try self.asmRegisterRegister(.cvtsd2ss, dst_reg, src_mcv.getReg().?.to128())2346 .cvtsd2ss,
2325 else2347 dst_reg,
2326 try self.asmRegisterMemory(.cvtsd2ss, dst_reg, src_mcv.mem(.qword));2348 (if (src_mcv.isRegister())
2349 src_mcv.getReg().?
2350 else
2351 try self.copyToTmpRegister(src_ty, src_mcv)).to128(),
2352 );
2327 } else return self.fail("TODO implement airFptrunc from {} to {}", .{2353 } else return self.fail("TODO implement airFptrunc from {} to {}", .{
2328 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),2354 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
2329 });2355 });
...@@ -2360,20 +2386,31 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {...@@ -2360,20 +2386,31 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
2360 }),2386 }),
2361 }2387 }
2362 } else if (src_bits == 32 and dst_bits == 64) {2388 } else if (src_bits == 32 and dst_bits == 64) {
2363 if (self.hasFeature(.avx)) if (src_mcv.isRegister()) try self.asmRegisterRegisterRegister(2389 if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
2364 .vcvtss2sd,2390 .vcvtss2sd,
2365 dst_reg,2391 dst_reg,
2366 dst_reg,2392 dst_reg,
2367 src_mcv.getReg().?.to128(),2393 src_mcv.mem(.dword),
2368 ) else try self.asmRegisterRegisterMemory(2394 ) else try self.asmRegisterRegisterRegister(
2369 .vcvtss2sd,2395 .vcvtss2sd,
2370 dst_reg,2396 dst_reg,
2371 dst_reg,2397 dst_reg,
2398 (if (src_mcv.isRegister())
2399 src_mcv.getReg().?
2400 else
2401 try self.copyToTmpRegister(src_ty, src_mcv)).to128(),
2402 ) else if (src_mcv.isMemory()) try self.asmRegisterMemory(
2403 .cvtss2sd,
2404 dst_reg,
2372 src_mcv.mem(.dword),2405 src_mcv.mem(.dword),
2373 ) else if (src_mcv.isRegister())2406 ) else try self.asmRegisterRegister(
2374 try self.asmRegisterRegister(.cvtss2sd, dst_reg, src_mcv.getReg().?.to128())2407 .cvtss2sd,
2375 else2408 dst_reg,
2376 try self.asmRegisterMemory(.cvtss2sd, dst_reg, src_mcv.mem(.dword));2409 (if (src_mcv.isRegister())
2410 src_mcv.getReg().?
2411 else
2412 try self.copyToTmpRegister(src_ty, src_mcv)).to128(),
2413 );
2377 } else return self.fail("TODO implement airFpext from {} to {}", .{2414 } else return self.fail("TODO implement airFpext from {} to {}", .{
2378 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),2415 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
2379 });2416 });
...@@ -4532,7 +4569,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4532,7 +4569,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
4532 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);4569 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
45334570
4534 const result: MCValue = result: {4571 const result: MCValue = result: {
4535 const tag = if (@as(?Mir.Inst.Tag, switch (ty.zigTypeTag()) {4572 const mir_tag = if (@as(?Mir.Inst.Tag, switch (ty.zigTypeTag()) {
4536 .Float => switch (ty.floatBits(self.target.*)) {4573 .Float => switch (ty.floatBits(self.target.*)) {
4537 16 => if (self.hasFeature(.f16c)) {4574 16 => if (self.hasFeature(.f16c)) {
4538 const mat_src_reg = if (src_mcv.isRegister())4575 const mat_src_reg = if (src_mcv.isRegister())
...@@ -4558,11 +4595,14 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4558,11 +4595,14 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
4558 .Float => switch (ty.childType().floatBits(self.target.*)) {4595 .Float => switch (ty.childType().floatBits(self.target.*)) {
4559 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) {4596 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) {
4560 1 => {4597 1 => {
4561 const mat_src_reg = if (src_mcv.isRegister())4598 try self.asmRegisterRegister(
4562 src_mcv.getReg().?4599 .vcvtph2ps,
4563 else4600 dst_reg,
4564 try self.copyToTmpRegister(ty, src_mcv);4601 (if (src_mcv.isRegister())
4565 try self.asmRegisterRegister(.vcvtph2ps, dst_reg, mat_src_reg.to128());4602 src_mcv.getReg().?
4603 else
4604 try self.copyToTmpRegister(ty, src_mcv)).to128(),
4605 );
4566 try self.asmRegisterRegisterRegister(.vsqrtss, dst_reg, dst_reg, dst_reg);4606 try self.asmRegisterRegisterRegister(.vsqrtss, dst_reg, dst_reg, dst_reg);
4567 try self.asmRegisterRegisterImmediate(4607 try self.asmRegisterRegisterImmediate(
4568 .vcvtps2ph,4608 .vcvtps2ph,
...@@ -4574,16 +4614,19 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4574,16 +4614,19 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
4574 },4614 },
4575 2...8 => {4615 2...8 => {
4576 const wide_reg = registerAlias(dst_reg, abi_size * 2);4616 const wide_reg = registerAlias(dst_reg, abi_size * 2);
4577 if (src_mcv.isRegister()) try self.asmRegisterRegister(4617 if (src_mcv.isMemory()) try self.asmRegisterMemory(
4578 .vcvtph2ps,
4579 wide_reg,
4580 src_mcv.getReg().?.to128(),
4581 ) else try self.asmRegisterMemory(
4582 .vcvtph2ps,4618 .vcvtph2ps,
4583 wide_reg,4619 wide_reg,
4584 src_mcv.mem(Memory.PtrSize.fromSize(4620 src_mcv.mem(Memory.PtrSize.fromSize(
4585 @intCast(u32, @divExact(wide_reg.bitSize(), 16)),4621 @intCast(u32, @divExact(wide_reg.bitSize(), 16)),
4586 )),4622 )),
4623 ) else try self.asmRegisterRegister(
4624 .vcvtph2ps,
4625 wide_reg,
4626 (if (src_mcv.isRegister())
4627 src_mcv.getReg().?
4628 else
4629 try self.copyToTmpRegister(ty, src_mcv)).to128(),
4587 );4630 );
4588 try self.asmRegisterRegister(.vsqrtps, wide_reg, wide_reg);4631 try self.asmRegisterRegister(.vsqrtps, wide_reg, wide_reg);
4589 try self.asmRegisterRegisterImmediate(4632 try self.asmRegisterRegisterImmediate(
...@@ -4617,26 +4660,32 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {...@@ -4617,26 +4660,32 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
4617 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{4660 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{
4618 ty.fmt(self.bin_file.options.module.?),4661 ty.fmt(self.bin_file.options.module.?),
4619 });4662 });
4620 switch (tag) {4663 switch (mir_tag) {
4621 .vsqrtss, .vsqrtsd => if (src_mcv.isRegister()) try self.asmRegisterRegisterRegister(4664 .vsqrtss, .vsqrtsd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
4622 tag,4665 mir_tag,
4623 dst_reg,4666 dst_reg,
4624 dst_reg,4667 dst_reg,
4625 registerAlias(src_mcv.getReg().?, abi_size),4668 src_mcv.mem(Memory.PtrSize.fromSize(abi_size)),
4626 ) else try self.asmRegisterRegisterMemory(4669 ) else try self.asmRegisterRegisterRegister(
4627 tag,4670 mir_tag,
4628 dst_reg,4671 dst_reg,
4629 dst_reg,4672 dst_reg,
4630 src_mcv.mem(Memory.PtrSize.fromSize(abi_size)),4673 registerAlias(if (src_mcv.isRegister())
4674 src_mcv.getReg().?
4675 else
4676 try self.copyToTmpRegister(ty, src_mcv), abi_size),
4631 ),4677 ),
4632 else => if (src_mcv.isRegister()) try self.asmRegisterRegister(4678 else => if (src_mcv.isMemory()) try self.asmRegisterMemory(
4633 tag,4679 mir_tag,
4634 dst_reg,
4635 registerAlias(src_mcv.getReg().?, abi_size),
4636 ) else try self.asmRegisterMemory(
4637 tag,
4638 dst_reg,4680 dst_reg,
4639 src_mcv.mem(Memory.PtrSize.fromSize(abi_size)),4681 src_mcv.mem(Memory.PtrSize.fromSize(abi_size)),
4682 ) else try self.asmRegisterRegister(
4683 mir_tag,
4684 dst_reg,
4685 registerAlias(if (src_mcv.isRegister())
4686 src_mcv.getReg().?
4687 else
4688 try self.copyToTmpRegister(ty, src_mcv), abi_size),
4640 ),4689 ),
4641 }4690 }
4642 break :result dst_mcv;4691 break :result dst_mcv;
...@@ -5800,25 +5849,22 @@ fn genMulDivBinOp(...@@ -5800,25 +5849,22 @@ fn genMulDivBinOp(
5800 }5849 }
5801}5850}
58025851
5803/// Result is always a register.
5804fn genBinOp(5852fn genBinOp(
5805 self: *Self,5853 self: *Self,
5806 maybe_inst: ?Air.Inst.Index,5854 maybe_inst: ?Air.Inst.Index,
5807 tag: Air.Inst.Tag,5855 air_tag: Air.Inst.Tag,
5808 lhs_air: Air.Inst.Ref,5856 lhs_air: Air.Inst.Ref,
5809 rhs_air: Air.Inst.Ref,5857 rhs_air: Air.Inst.Ref,
5810) !MCValue {5858) !MCValue {
5811 const lhs = try self.resolveInst(lhs_air);5859 const lhs_mcv = try self.resolveInst(lhs_air);
5812 const rhs = try self.resolveInst(rhs_air);5860 const rhs_mcv = try self.resolveInst(rhs_air);
5813 const lhs_ty = self.air.typeOf(lhs_air);5861 const lhs_ty = self.air.typeOf(lhs_air);
5814 const rhs_ty = self.air.typeOf(rhs_air);5862 const rhs_ty = self.air.typeOf(rhs_air);
5815 if (lhs_ty.zigTypeTag() == .Vector) {5863 const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*));
5816 return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)});
5817 }
58185864
5819 switch (lhs) {5865 switch (lhs_mcv) {
5820 .immediate => |imm| switch (imm) {5866 .immediate => |imm| switch (imm) {
5821 0 => switch (tag) {5867 0 => switch (air_tag) {
5822 .sub, .subwrap => return self.genUnOp(maybe_inst, .neg, rhs_air),5868 .sub, .subwrap => return self.genUnOp(maybe_inst, .neg, rhs_air),
5823 else => {},5869 else => {},
5824 },5870 },
...@@ -5827,9 +5873,10 @@ fn genBinOp(...@@ -5827,9 +5873,10 @@ fn genBinOp(
5827 else => {},5873 else => {},
5828 }5874 }
58295875
5830 const is_commutative = switch (tag) {5876 const is_commutative = switch (air_tag) {
5831 .add,5877 .add,
5832 .addwrap,5878 .addwrap,
5879 .mul,
5833 .bool_or,5880 .bool_or,
5834 .bit_or,5881 .bit_or,
5835 .bool_and,5882 .bool_and,
...@@ -5841,48 +5888,42 @@ fn genBinOp(...@@ -5841,48 +5888,42 @@ fn genBinOp(
58415888
5842 else => false,5889 else => false,
5843 };5890 };
5844 const dst_mem_ok = switch (tag) {5891 const vec_op = switch (lhs_ty.zigTypeTag()) {
5845 .add,5892 else => false,
5846 .addwrap,5893 .Float, .Vector => true,
5847 .sub,
5848 .subwrap,
5849 .mul,
5850 .div_float,
5851 .div_exact,
5852 .div_trunc,
5853 .div_floor,
5854 => !lhs_ty.isRuntimeFloat(),
5855
5856 else => true,
5857 };5894 };
58585895
5859 const lhs_lock: ?RegisterLock = switch (lhs) {5896 const lhs_lock: ?RegisterLock = switch (lhs_mcv) {
5860 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),5897 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
5861 else => null,5898 else => null,
5862 };5899 };
5863 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);5900 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
58645901
5865 const rhs_lock: ?RegisterLock = switch (rhs) {5902 const rhs_lock: ?RegisterLock = switch (rhs_mcv) {
5866 .register => |reg| self.register_manager.lockReg(reg),5903 .register => |reg| self.register_manager.lockReg(reg),
5867 else => null,5904 else => null,
5868 };5905 };
5869 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);5906 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
58705907
5871 var flipped: bool = false;5908 var flipped = false;
5909 var copied_to_dst = true;
5872 const dst_mcv: MCValue = dst: {5910 const dst_mcv: MCValue = dst: {
5873 if (maybe_inst) |inst| {5911 if (maybe_inst) |inst| {
5874 if ((dst_mem_ok or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) {5912 if ((!vec_op or lhs_mcv.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs_mcv)) {
5875 break :dst lhs;5913 break :dst lhs_mcv;
5876 }5914 }
5877 if (is_commutative and (dst_mem_ok or rhs.isRegister()) and5915 if (is_commutative and (!vec_op or rhs_mcv.isRegister()) and
5878 self.reuseOperand(inst, rhs_air, 1, rhs))5916 self.reuseOperand(inst, rhs_air, 1, rhs_mcv))
5879 {5917 {
5880 flipped = true;5918 flipped = true;
5881 break :dst rhs;5919 break :dst rhs_mcv;
5882 }5920 }
5883 }5921 }
5884 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true);5922 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true);
5885 try self.genCopy(lhs_ty, dst_mcv, lhs);5923 if (vec_op and lhs_mcv.isRegister() and self.hasFeature(.avx))
5924 copied_to_dst = false
5925 else
5926 try self.genCopy(lhs_ty, dst_mcv, lhs_mcv);
5886 break :dst dst_mcv;5927 break :dst dst_mcv;
5887 };5928 };
5888 const dst_lock: ?RegisterLock = switch (dst_mcv) {5929 const dst_lock: ?RegisterLock = switch (dst_mcv) {
...@@ -5891,160 +5932,47 @@ fn genBinOp(...@@ -5891,160 +5932,47 @@ fn genBinOp(
5891 };5932 };
5892 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);5933 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
58935934
5894 const src_mcv = if (flipped) lhs else rhs;5935 const src_mcv = if (flipped) lhs_mcv else rhs_mcv;
5895 switch (tag) {5936 if (!vec_op) {
5896 .add,5937 switch (air_tag) {
5897 .addwrap,5938 .add,
5898 => try self.genBinOpMir(switch (lhs_ty.zigTypeTag()) {5939 .addwrap,
5899 else => .add,5940 => try self.genBinOpMir(.add, lhs_ty, dst_mcv, src_mcv),
5900 .Float => switch (lhs_ty.floatBits(self.target.*)) {
5901 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse))
5902 .addss
5903 else
5904 return self.fail("TODO implement genBinOp for {s} {} without sse", .{
5905 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5906 }),
5907 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2))
5908 .addsd
5909 else
5910 return self.fail("TODO implement genBinOp for {s} {} without sse2", .{
5911 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5912 }),
5913 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5914 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5915 }),
5916 },
5917 }, lhs_ty, dst_mcv, src_mcv),
5918
5919 .sub,
5920 .subwrap,
5921 => try self.genBinOpMir(switch (lhs_ty.zigTypeTag()) {
5922 else => .sub,
5923 .Float => switch (lhs_ty.floatBits(self.target.*)) {
5924 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse))
5925 .subss
5926 else
5927 return self.fail("TODO implement genBinOp for {s} {} without sse", .{
5928 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5929 }),
5930 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2))
5931 .subsd
5932 else
5933 return self.fail("TODO implement genBinOp for {s} {} without sse2", .{
5934 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5935 }),
5936 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5937 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5938 }),
5939 },
5940 }, lhs_ty, dst_mcv, src_mcv),
5941
5942 .mul => try self.genBinOpMir(switch (lhs_ty.zigTypeTag()) {
5943 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5944 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5945 }),
5946 .Float => switch (lhs_ty.floatBits(self.target.*)) {
5947 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse))
5948 .mulss
5949 else
5950 return self.fail("TODO implement genBinOp for {s} {} without sse", .{
5951 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5952 }),
5953 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2))
5954 .mulsd
5955 else
5956 return self.fail("TODO implement genBinOp for {s} {} without sse2", .{
5957 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5958 }),
5959 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5960 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5961 }),
5962 },
5963 }, lhs_ty, dst_mcv, src_mcv),
59645941
5965 .div_float,5942 .sub,
5966 .div_exact,5943 .subwrap,
5967 .div_trunc,5944 => try self.genBinOpMir(.sub, lhs_ty, dst_mcv, src_mcv),
5968 .div_floor,
5969 => {
5970 try self.genBinOpMir(switch (lhs_ty.zigTypeTag()) {
5971 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5972 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5973 }),
5974 .Float => switch (lhs_ty.floatBits(self.target.*)) {
5975 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse))
5976 .divss
5977 else
5978 return self.fail("TODO implement genBinOp for {s} {} without sse", .{
5979 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5980 }),
5981 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2))
5982 .divsd
5983 else
5984 return self.fail("TODO implement genBinOp for {s} {} without sse2", .{
5985 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5986 }),
5987 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5988 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5989 }),
5990 },
5991 }, lhs_ty, dst_mcv, src_mcv);
5992 switch (tag) {
5993 .div_float,
5994 .div_exact,
5995 => {},
5996 .div_trunc,
5997 .div_floor,
5998 => if (self.hasFeature(.sse4_1)) {
5999 const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*));
6000 const dst_alias = registerAlias(dst_mcv.register, abi_size);
6001 try self.asmRegisterRegisterImmediate(switch (lhs_ty.floatBits(self.target.*)) {
6002 32 => .roundss,
6003 64 => .roundsd,
6004 else => unreachable,
6005 }, dst_alias, dst_alias, Immediate.u(switch (tag) {
6006 .div_trunc => 0b1_0_11,
6007 .div_floor => 0b1_0_01,
6008 else => unreachable,
6009 }));
6010 } else return self.fail("TODO implement genBinOp for {s} {} without sse4_1", .{
6011 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
6012 }),
6013 else => unreachable,
6014 }
6015 },
60165945
6017 .ptr_add,5946 .ptr_add,
6018 .ptr_sub,5947 .ptr_sub,
6019 => {5948 => {
6020 const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv);5949 const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv);
6021 const tmp_mcv = MCValue{ .register = tmp_reg };5950 const tmp_mcv = MCValue{ .register = tmp_reg };
6022 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);5951 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
6023 defer self.register_manager.unlockReg(tmp_lock);5952 defer self.register_manager.unlockReg(tmp_lock);
60245953
6025 const elem_size = lhs_ty.elemType2().abiSize(self.target.*);5954 const elem_size = lhs_ty.elemType2().abiSize(self.target.*);
6026 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });5955 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });
6027 try self.genBinOpMir(switch (tag) {5956 try self.genBinOpMir(switch (air_tag) {
6028 .ptr_add => .add,5957 .ptr_add => .add,
6029 .ptr_sub => .sub,5958 .ptr_sub => .sub,
6030 else => unreachable,5959 else => unreachable,
6031 }, lhs_ty, dst_mcv, tmp_mcv);5960 }, lhs_ty, dst_mcv, tmp_mcv);
6032 },5961 },
60335962
6034 .bool_or,5963 .bool_or,
6035 .bit_or,5964 .bit_or,
6036 => try self.genBinOpMir(.@"or", lhs_ty, dst_mcv, src_mcv),5965 => try self.genBinOpMir(.@"or", lhs_ty, dst_mcv, src_mcv),
60375966
6038 .bool_and,5967 .bool_and,
6039 .bit_and,5968 .bit_and,
6040 => try self.genBinOpMir(.@"and", lhs_ty, dst_mcv, src_mcv),5969 => try self.genBinOpMir(.@"and", lhs_ty, dst_mcv, src_mcv),
60415970
6042 .xor => try self.genBinOpMir(.xor, lhs_ty, dst_mcv, src_mcv),5971 .xor => try self.genBinOpMir(.xor, lhs_ty, dst_mcv, src_mcv),
60435972
6044 .min,5973 .min,
6045 .max,5974 .max,
6046 => switch (lhs_ty.zigTypeTag()) {5975 => {
6047 .Int => {
6048 const mat_src_mcv: MCValue = if (switch (src_mcv) {5976 const mat_src_mcv: MCValue = if (switch (src_mcv) {
6049 .immediate,5977 .immediate,
6050 .eflags,5978 .eflags,
...@@ -6070,12 +5998,12 @@ fn genBinOp(...@@ -6070,12 +5998,12 @@ fn genBinOp(
60705998
6071 const int_info = lhs_ty.intInfo(self.target.*);5999 const int_info = lhs_ty.intInfo(self.target.*);
6072 const cc: Condition = switch (int_info.signedness) {6000 const cc: Condition = switch (int_info.signedness) {
6073 .unsigned => switch (tag) {6001 .unsigned => switch (air_tag) {
6074 .min => .a,6002 .min => .a,
6075 .max => .b,6003 .max => .b,
6076 else => unreachable,6004 else => unreachable,
6077 },6005 },
6078 .signed => switch (tag) {6006 .signed => switch (air_tag) {
6079 .min => .g,6007 .min => .g,
6080 .max => .l,6008 .max => .l,
6081 else => unreachable,6009 else => unreachable,
...@@ -6134,26 +6062,222 @@ fn genBinOp(...@@ -6134,26 +6062,222 @@ fn genBinOp(
6134 }6062 }
6135 try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg });6063 try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg });
6136 },6064 },
6137 .Float => try self.genBinOpMir(switch (lhs_ty.floatBits(self.target.*)) {6065
6138 32 => switch (tag) {
6139 .min => .minss,
6140 .max => .maxss,
6141 else => unreachable,
6142 },
6143 64 => switch (tag) {
6144 .min => .minsd,
6145 .max => .maxsd,
6146 else => unreachable,
6147 },
6148 else => return self.fail("TODO implement genBinOp for {s} {}", .{
6149 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
6150 }),
6151 }, lhs_ty, dst_mcv, src_mcv),
6152 else => return self.fail("TODO implement genBinOp for {s} {}", .{6066 else => return self.fail("TODO implement genBinOp for {s} {}", .{
6153 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),6067 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6154 }),6068 }),
6155 },6069 }
6070 return dst_mcv;
6071 }
61566072
6073 const mir_tag = if (@as(?Mir.Inst.Tag, switch (lhs_ty.zigTypeTag()) {
6074 else => unreachable,
6075 .Float => switch (lhs_ty.floatBits(self.target.*)) {
6076 32 => switch (air_tag) {
6077 .add => if (self.hasFeature(.avx)) .vaddss else .addss,
6078 .sub => if (self.hasFeature(.avx)) .vsubss else .subss,
6079 .mul => if (self.hasFeature(.avx)) .vmulss else .mulss,
6080 .div_float,
6081 .div_trunc,
6082 .div_floor,
6083 .div_exact,
6084 => if (self.hasFeature(.avx)) .vdivss else .divss,
6085 .max => if (self.hasFeature(.avx)) .vmaxss else .maxss,
6086 .min => if (self.hasFeature(.avx)) .vminss else .minss,
6087 else => unreachable,
6088 },
6089 64 => switch (air_tag) {
6090 .add => if (self.hasFeature(.avx)) .vaddsd else .addsd,
6091 .sub => if (self.hasFeature(.avx)) .vsubsd else .subsd,
6092 .mul => if (self.hasFeature(.avx)) .vmulsd else .mulsd,
6093 .div_float,
6094 .div_trunc,
6095 .div_floor,
6096 .div_exact,
6097 => if (self.hasFeature(.avx)) .vdivsd else .divsd,
6098 .max => if (self.hasFeature(.avx)) .vmaxsd else .maxsd,
6099 .min => if (self.hasFeature(.avx)) .vminsd else .minsd,
6100 else => unreachable,
6101 },
6102 16, 80, 128 => null,
6103 else => unreachable,
6104 },
6105 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
6106 else => null,
6107 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
6108 32 => switch (lhs_ty.vectorLen()) {
6109 1 => switch (air_tag) {
6110 .add => if (self.hasFeature(.avx)) .vaddss else .addss,
6111 .sub => if (self.hasFeature(.avx)) .vsubss else .subss,
6112 .mul => if (self.hasFeature(.avx)) .vmulss else .mulss,
6113 .div_float,
6114 .div_trunc,
6115 .div_floor,
6116 .div_exact,
6117 => if (self.hasFeature(.avx)) .vdivss else .divss,
6118 .max => if (self.hasFeature(.avx)) .vmaxss else .maxss,
6119 .min => if (self.hasFeature(.avx)) .vminss else .minss,
6120 else => unreachable,
6121 },
6122 2...4 => switch (air_tag) {
6123 .add => if (self.hasFeature(.avx)) .vaddps else .addps,
6124 .sub => if (self.hasFeature(.avx)) .vsubps else .subps,
6125 .mul => if (self.hasFeature(.avx)) .vmulps else .mulps,
6126 .div_float,
6127 .div_trunc,
6128 .div_floor,
6129 .div_exact,
6130 => if (self.hasFeature(.avx)) .vdivps else .divps,
6131 .max => if (self.hasFeature(.avx)) .vmaxps else .maxps,
6132 .min => if (self.hasFeature(.avx)) .vminps else .minps,
6133 else => unreachable,
6134 },
6135 5...8 => if (self.hasFeature(.avx)) switch (air_tag) {
6136 .add => .vaddps,
6137 .sub => .vsubps,
6138 .mul => .vmulps,
6139 .div_float, .div_trunc, .div_floor, .div_exact => .vdivps,
6140 .max => .vmaxps,
6141 .min => .vminps,
6142 else => unreachable,
6143 } else null,
6144 else => null,
6145 },
6146 64 => switch (lhs_ty.vectorLen()) {
6147 1 => switch (air_tag) {
6148 .add => if (self.hasFeature(.avx)) .vaddsd else .addsd,
6149 .sub => if (self.hasFeature(.avx)) .vsubsd else .subsd,
6150 .mul => if (self.hasFeature(.avx)) .vmulsd else .mulsd,
6151 .div_float,
6152 .div_trunc,
6153 .div_floor,
6154 .div_exact,
6155 => if (self.hasFeature(.avx)) .vdivsd else .divsd,
6156 .max => if (self.hasFeature(.avx)) .vmaxsd else .maxsd,
6157 .min => if (self.hasFeature(.avx)) .vminsd else .minsd,
6158 else => unreachable,
6159 },
6160 2 => switch (air_tag) {
6161 .add => if (self.hasFeature(.avx)) .vaddpd else .addpd,
6162 .sub => if (self.hasFeature(.avx)) .vsubpd else .subpd,
6163 .mul => if (self.hasFeature(.avx)) .vmulpd else .mulpd,
6164 .div_float,
6165 .div_trunc,
6166 .div_floor,
6167 .div_exact,
6168 => if (self.hasFeature(.avx)) .vdivpd else .divpd,
6169 .max => if (self.hasFeature(.avx)) .vmaxpd else .maxpd,
6170 .min => if (self.hasFeature(.avx)) .vminpd else .minpd,
6171 else => unreachable,
6172 },
6173 3...4 => if (self.hasFeature(.avx)) switch (air_tag) {
6174 .add => .vaddpd,
6175 .sub => .vsubpd,
6176 .mul => .vmulpd,
6177 .div_float, .div_trunc, .div_floor, .div_exact => .vdivpd,
6178 .max => .vmaxpd,
6179 .min => .vminpd,
6180 else => unreachable,
6181 } else null,
6182 else => null,
6183 },
6184 16, 80, 128 => null,
6185 else => unreachable,
6186 },
6187 },
6188 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
6189 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6190 });
6191 const dst_alias = registerAlias(dst_mcv.getReg().?, abi_size);
6192 if (self.hasFeature(.avx)) {
6193 const src1_alias =
6194 if (copied_to_dst) dst_alias else registerAlias(lhs_mcv.getReg().?, abi_size);
6195 if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
6196 mir_tag,
6197 dst_alias,
6198 src1_alias,
6199 src_mcv.mem(Memory.PtrSize.fromSize(abi_size)),
6200 ) else try self.asmRegisterRegisterRegister(
6201 mir_tag,
6202 dst_alias,
6203 src1_alias,
6204 registerAlias(if (src_mcv.isRegister())
6205 src_mcv.getReg().?
6206 else
6207 try self.copyToTmpRegister(rhs_ty, src_mcv), abi_size),
6208 );
6209 } else {
6210 assert(copied_to_dst);
6211 if (src_mcv.isMemory()) try self.asmRegisterMemory(
6212 mir_tag,
6213 dst_alias,
6214 src_mcv.mem(Memory.PtrSize.fromSize(abi_size)),
6215 ) else try self.asmRegisterRegister(
6216 mir_tag,
6217 dst_alias,
6218 registerAlias(if (src_mcv.isRegister())
6219 src_mcv.getReg().?
6220 else
6221 try self.copyToTmpRegister(rhs_ty, src_mcv), abi_size),
6222 );
6223 }
6224 switch (air_tag) {
6225 .add, .sub, .mul, .div_float, .div_exact => {},
6226 .div_trunc, .div_floor => if (self.hasFeature(.sse4_1)) {
6227 const round_tag = if (@as(?Mir.Inst.Tag, switch (lhs_ty.zigTypeTag()) {
6228 .Float => switch (lhs_ty.floatBits(self.target.*)) {
6229 32 => if (self.hasFeature(.avx)) .vroundss else .roundss,
6230 64 => if (self.hasFeature(.avx)) .vroundsd else .roundsd,
6231 16, 80, 128 => null,
6232 else => unreachable,
6233 },
6234 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
6235 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
6236 32 => switch (lhs_ty.vectorLen()) {
6237 1 => if (self.hasFeature(.avx)) .vroundss else .roundss,
6238 2...4 => if (self.hasFeature(.avx)) .vroundps else .roundps,
6239 5...8 => if (self.hasFeature(.avx)) .vroundps else null,
6240 else => null,
6241 },
6242 64 => switch (lhs_ty.vectorLen()) {
6243 1 => if (self.hasFeature(.avx)) .vroundsd else .roundsd,
6244 2 => if (self.hasFeature(.avx)) .vroundpd else .roundpd,
6245 3...4 => if (self.hasFeature(.avx)) .vroundpd else null,
6246 else => null,
6247 },
6248 16, 80, 128 => null,
6249 else => unreachable,
6250 },
6251 else => null,
6252 },
6253 else => unreachable,
6254 })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{
6255 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6256 });
6257 const round_mode = Immediate.u(switch (air_tag) {
6258 .div_trunc => 0b1_0_11,
6259 .div_floor => 0b1_0_01,
6260 else => unreachable,
6261 });
6262 switch (round_tag) {
6263 .vroundss, .vroundsd => try self.asmRegisterRegisterRegisterImmediate(
6264 round_tag,
6265 dst_alias,
6266 dst_alias,
6267 dst_alias,
6268 round_mode,
6269 ),
6270 else => try self.asmRegisterRegisterImmediate(
6271 round_tag,
6272 dst_alias,
6273 dst_alias,
6274 round_mode,
6275 ),
6276 }
6277 } else return self.fail("TODO implement genBinOp for {s} {} without sse4_1", .{
6278 @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?),
6279 }),
6280 .max, .min => {}, // TODO: unordered select
6157 else => unreachable,6281 else => unreachable,
6158 }6282 }
6159 return dst_mcv;6283 return dst_mcv;
...@@ -6186,20 +6310,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -6186,20 +6310,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
6186 .register_overflow,6310 .register_overflow,
6187 .reserved_frame,6311 .reserved_frame,
6188 => unreachable,6312 => unreachable,
6189 .register => |src_reg| switch (ty.zigTypeTag()) {6313 .register => |src_reg| try self.asmRegisterRegister(
6190 .Float => {6314 mir_tag,
6191 if (!Target.x86.featureSetHas(self.target.cpu.features, .sse))6315 dst_alias,
6192 return self.fail("TODO genBinOpMir for {s} {} without sse", .{6316 registerAlias(src_reg, abi_size),
6193 @tagName(mir_tag), ty.fmt(self.bin_file.options.module.?),6317 ),
6194 });
6195 return self.asmRegisterRegister(mir_tag, dst_reg.to128(), src_reg.to128());
6196 },
6197 else => try self.asmRegisterRegister(
6198 mir_tag,
6199 dst_alias,
6200 registerAlias(src_reg, abi_size),
6201 ),
6202 },
6203 .immediate => |imm| switch (self.regBitSize(ty)) {6318 .immediate => |imm| switch (self.regBitSize(ty)) {
6204 8 => try self.asmRegisterImmediate(6319 8 => try self.asmRegisterImmediate(
6205 mir_tag,6320 mir_tag,
...@@ -9646,7 +9761,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -9646,7 +9761,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
9646 lock.* = self.register_manager.lockRegAssumeUnused(reg);9761 lock.* = self.register_manager.lockRegAssumeUnused(reg);
9647 }9762 }
96489763
9649 const tag = if (@as(9764 const mir_tag = if (@as(
9650 ?Mir.Inst.Tag,9765 ?Mir.Inst.Tag,
9651 if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 }))9766 if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 }))
9652 switch (ty.zigTypeTag()) {9767 switch (ty.zigTypeTag()) {
...@@ -9741,20 +9856,17 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -9741,20 +9856,17 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
9741 const abi_size = @intCast(u32, ty.abiSize(self.target.*));9856 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
9742 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);9857 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
9743 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);9858 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
9744 if (mops[2].isRegister())9859 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
9745 try self.asmRegisterRegisterRegister(9860 mir_tag,
9746 tag,9861 mop1_reg,
9747 mop1_reg,9862 mop2_reg,
9748 mop2_reg,9863 registerAlias(mops[2].getReg().?, abi_size),
9749 registerAlias(mops[2].getReg().?, abi_size),9864 ) else try self.asmRegisterRegisterMemory(
9750 )9865 mir_tag,
9751 else9866 mop1_reg,
9752 try self.asmRegisterRegisterMemory(9867 mop2_reg,
9753 tag,9868 mops[2].mem(Memory.PtrSize.fromSize(abi_size)),
9754 mop1_reg,9869 );
9755 mop2_reg,
9756 mops[2].mem(Memory.PtrSize.fromSize(abi_size)),
9757 );
9758 return self.finishAir(inst, mops[0], ops);9870 return self.finishAir(inst, mops[0], ops);
9759}9871}
97609872
src/arch/x86_64/Encoding.zig+21-13
...@@ -262,61 +262,69 @@ pub const Mnemonic = enum {...@@ -262,61 +262,69 @@ pub const Mnemonic = enum {
262 // MMX262 // MMX
263 movd,263 movd,
264 // SSE264 // SSE
265 addss,265 addps, addss,
266 andps,266 andps,
267 andnps,267 andnps,
268 cmpss,268 cmpss,
269 cvtsi2ss,269 cvtsi2ss,
270 divss,270 divps, divss,
271 maxss, minss,271 maxps, maxss,
272 minps, minss,
272 movaps, movss, movups,273 movaps, movss, movups,
273 mulss,274 mulps, mulss,
274 orps,275 orps,
275 pextrw, pinsrw,276 pextrw, pinsrw,
276 sqrtps,277 sqrtps, sqrtss,
277 sqrtss,278 subps, subss,
278 subss,
279 ucomiss,279 ucomiss,
280 xorps,280 xorps,
281 // SSE2281 // SSE2
282 addsd,282 addpd, addsd,
283 andpd,283 andpd,
284 andnpd,284 andnpd,
285 //cmpsd,285 //cmpsd,
286 cvtsd2ss, cvtsi2sd, cvtss2sd,286 cvtsd2ss, cvtsi2sd, cvtss2sd,
287 divsd,287 divpd, divsd,
288 maxsd, minsd,288 maxpd, maxsd,
289 minpd, minsd,
289 movapd,290 movapd,
290 movq, //movd, movsd,291 movq, //movd, movsd,
291 movupd,292 movupd,
292 mulsd,293 mulpd, mulsd,
293 orpd,294 orpd,
294 pshufhw, pshuflw,295 pshufhw, pshuflw,
295 psrld, psrlq, psrlw,296 psrld, psrlq, psrlw,
296 punpckhbw, punpckhdq, punpckhqdq, punpckhwd,297 punpckhbw, punpckhdq, punpckhqdq, punpckhwd,
297 punpcklbw, punpckldq, punpcklqdq, punpcklwd,298 punpcklbw, punpckldq, punpcklqdq, punpcklwd,
298 sqrtpd, sqrtsd,299 sqrtpd, sqrtsd,
299 subsd,300 subpd, subsd,
300 ucomisd,301 ucomisd,
301 xorpd,302 xorpd,
302 // SSE3303 // SSE3
303 movddup, movshdup, movsldup,304 movddup, movshdup, movsldup,
304 // SSE4.1305 // SSE4.1
305 roundsd, roundss,306 roundpd, roundps, roundsd, roundss,
306 // AVX307 // AVX
308 vaddpd, vaddps, vaddsd, vaddss,
307 vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd,309 vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd,
310 vdivpd, vdivps, vdivsd, vdivss,
311 vmaxpd, vmaxps, vmaxsd, vmaxss,
312 vminpd, vminps, vminsd, vminss,
308 vmovapd, vmovaps,313 vmovapd, vmovaps,
309 vmovddup,314 vmovddup,
310 vmovsd,315 vmovsd,
311 vmovshdup, vmovsldup,316 vmovshdup, vmovsldup,
312 vmovss,317 vmovss,
313 vmovupd, vmovups,318 vmovupd, vmovups,
319 vmulpd, vmulps, vmulsd, vmulss,
314 vpextrw, vpinsrw,320 vpextrw, vpinsrw,
315 vpshufhw, vpshuflw,321 vpshufhw, vpshuflw,
316 vpsrld, vpsrlq, vpsrlw,322 vpsrld, vpsrlq, vpsrlw,
317 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,323 vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd,
318 vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd,324 vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd,
325 vroundpd, vroundps, vroundsd, vroundss,
319 vsqrtpd, vsqrtps, vsqrtsd, vsqrtss,326 vsqrtpd, vsqrtps, vsqrtsd, vsqrtss,
327 vsubpd, vsubps, vsubsd, vsubss,
320 // F16C328 // F16C
321 vcvtph2ps, vcvtps2ph,329 vcvtph2ps, vcvtps2ph,
322 // FMA330 // FMA
src/arch/x86_64/Lower.zig+49
...@@ -124,27 +124,34 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -124,27 +124,34 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
124 .xchg,124 .xchg,
125 .xor,125 .xor,
126126
127 .addps,
127 .addss,128 .addss,
128 .andnps,129 .andnps,
129 .andps,130 .andps,
130 .cmpss,131 .cmpss,
131 .cvtsi2ss,132 .cvtsi2ss,
133 .divps,
132 .divss,134 .divss,
135 .maxps,
133 .maxss,136 .maxss,
137 .minps,
134 .minss,138 .minss,
135 .movaps,139 .movaps,
136 .movss,140 .movss,
137 .movups,141 .movups,
142 .mulps,
138 .mulss,143 .mulss,
139 .orps,144 .orps,
140 .pextrw,145 .pextrw,
141 .pinsrw,146 .pinsrw,
142 .sqrtps,147 .sqrtps,
143 .sqrtss,148 .sqrtss,
149 .subps,
144 .subss,150 .subss,
145 .ucomiss,151 .ucomiss,
146 .xorps,152 .xorps,
147153
154 .addpd,
148 .addsd,155 .addsd,
149 .andnpd,156 .andnpd,
150 .andpd,157 .andpd,
...@@ -152,10 +159,14 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -152,10 +159,14 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
152 .cvtsd2ss,159 .cvtsd2ss,
153 .cvtsi2sd,160 .cvtsi2sd,
154 .cvtss2sd,161 .cvtss2sd,
162 .divpd,
155 .divsd,163 .divsd,
164 .maxpd,
156 .maxsd,165 .maxsd,
166 .minpd,
157 .minsd,167 .minsd,
158 .movsd,168 .movsd,
169 .mulpd,
159 .mulsd,170 .mulsd,
160 .orpd,171 .orpd,
161 .pshufhw,172 .pshufhw,
...@@ -173,6 +184,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -173,6 +184,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
173 .punpcklwd,184 .punpcklwd,
174 .sqrtpd,185 .sqrtpd,
175 .sqrtsd,186 .sqrtsd,
187 .subpd,
176 .subsd,188 .subsd,
177 .ucomisd,189 .ucomisd,
178 .xorpd,190 .xorpd,
...@@ -181,13 +193,31 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -181,13 +193,31 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
181 .movshdup,193 .movshdup,
182 .movsldup,194 .movsldup,
183195
196 .roundpd,
197 .roundps,
184 .roundsd,198 .roundsd,
185 .roundss,199 .roundss,
186200
201 .vaddpd,
202 .vaddps,
203 .vaddsd,
204 .vaddss,
187 .vcvtsd2ss,205 .vcvtsd2ss,
188 .vcvtsi2sd,206 .vcvtsi2sd,
189 .vcvtsi2ss,207 .vcvtsi2ss,
190 .vcvtss2sd,208 .vcvtss2sd,
209 .vdivpd,
210 .vdivps,
211 .vdivsd,
212 .vdivss,
213 .vmaxpd,
214 .vmaxps,
215 .vmaxsd,
216 .vmaxss,
217 .vminpd,
218 .vminps,
219 .vminsd,
220 .vminss,
191 .vmovapd,221 .vmovapd,
192 .vmovaps,222 .vmovaps,
193 .vmovddup,223 .vmovddup,
...@@ -197,6 +227,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -197,6 +227,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
197 .vmovss,227 .vmovss,
198 .vmovupd,228 .vmovupd,
199 .vmovups,229 .vmovups,
230 .vmulpd,
231 .vmulps,
232 .vmulsd,
233 .vmulss,
200 .vpextrw,234 .vpextrw,
201 .vpinsrw,235 .vpinsrw,
202 .vpshufhw,236 .vpshufhw,
...@@ -212,10 +246,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -212,10 +246,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
212 .vpunpckldq,246 .vpunpckldq,
213 .vpunpcklqdq,247 .vpunpcklqdq,
214 .vpunpcklwd,248 .vpunpcklwd,
249 .vroundpd,
250 .vroundps,
251 .vroundsd,
252 .vroundss,
215 .vsqrtpd,253 .vsqrtpd,
216 .vsqrtps,254 .vsqrtps,
217 .vsqrtsd,255 .vsqrtsd,
218 .vsqrtss,256 .vsqrtss,
257 .vsubpd,
258 .vsubps,
259 .vsubsd,
260 .vsubss,
219261
220 .vcvtph2ps,262 .vcvtph2ps,
221 .vcvtps2ph,263 .vcvtps2ph,
...@@ -304,6 +346,7 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {...@@ -304,6 +346,7 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
304 .lock_mi_rip_s,346 .lock_mi_rip_s,
305 => Immediate.s(@bitCast(i32, i)),347 => Immediate.s(@bitCast(i32, i)),
306348
349 .rrri,
307 .rri_u,350 .rri_u,
308 .ri_u,351 .ri_u,
309 .i_u,352 .i_u,
...@@ -429,6 +472,12 @@ fn mirGeneric(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -429,6 +472,12 @@ fn mirGeneric(lower: *Lower, inst: Mir.Inst) Error!void {
429 .{ .reg = inst.data.rrr.r2 },472 .{ .reg = inst.data.rrr.r2 },
430 .{ .reg = inst.data.rrr.r3 },473 .{ .reg = inst.data.rrr.r3 },
431 },474 },
475 .rrri => &.{
476 .{ .reg = inst.data.rrri.r1 },
477 .{ .reg = inst.data.rrri.r2 },
478 .{ .reg = inst.data.rrri.r3 },
479 .{ .imm = lower.imm(inst.ops, inst.data.rrri.i) },
480 },
432 .ri_s, .ri_u => &.{481 .ri_s, .ri_u => &.{
433 .{ .reg = inst.data.ri.r },482 .{ .reg = inst.data.ri.r },
434 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },483 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },
src/arch/x86_64/Mir.zig+104-11
...@@ -166,7 +166,9 @@ pub const Inst = struct {...@@ -166,7 +166,9 @@ pub const Inst = struct {
166 /// Logical exclusive-or166 /// Logical exclusive-or
167 xor,167 xor,
168168
169 /// Add single precision floating point values169 /// Add packed single-precision floating-point values
170 addps,
171 /// Add scalar single-precision floating-point values
170 addss,172 addss,
171 /// Bitwise logical and of packed single precision floating-point values173 /// Bitwise logical and of packed single precision floating-point values
172 andps,174 andps,
...@@ -176,11 +178,17 @@ pub const Inst = struct {...@@ -176,11 +178,17 @@ pub const Inst = struct {
176 cmpss,178 cmpss,
177 /// Convert doubleword integer to scalar single-precision floating-point value179 /// Convert doubleword integer to scalar single-precision floating-point value
178 cvtsi2ss,180 cvtsi2ss,
181 /// Divide packed single-precision floating-point values
182 divps,
179 /// Divide scalar single-precision floating-point values183 /// Divide scalar single-precision floating-point values
180 divss,184 divss,
181 /// Return maximum single-precision floating-point value185 /// Maximum of packed single-precision floating-point values
186 maxps,
187 /// Maximum of scalar single-precision floating-point values
182 maxss,188 maxss,
183 /// Return minimum single-precision floating-point value189 /// Minimum of packed single-precision floating-point values
190 minps,
191 /// Minimum of scalar single-precision floating-point values
184 minss,192 minss,
185 /// Move aligned packed single-precision floating-point values193 /// Move aligned packed single-precision floating-point values
186 movaps,194 movaps,
...@@ -188,6 +196,8 @@ pub const Inst = struct {...@@ -188,6 +196,8 @@ pub const Inst = struct {
188 movss,196 movss,
189 /// Move unaligned packed single-precision floating-point values197 /// Move unaligned packed single-precision floating-point values
190 movups,198 movups,
199 /// Multiply packed single-precision floating-point values
200 mulps,
191 /// Multiply scalar single-precision floating-point values201 /// Multiply scalar single-precision floating-point values
192 mulss,202 mulss,
193 /// Bitwise logical or of packed single precision floating-point values203 /// Bitwise logical or of packed single precision floating-point values
...@@ -196,18 +206,22 @@ pub const Inst = struct {...@@ -196,18 +206,22 @@ pub const Inst = struct {
196 pextrw,206 pextrw,
197 /// Insert word207 /// Insert word
198 pinsrw,208 pinsrw,
199 /// Square root of scalar single precision floating-point value209 /// Square root of packed single-precision floating-point values
200 sqrtps,210 sqrtps,
201 /// Subtract scalar single-precision floating-point values211 /// Square root of scalar single-precision floating-point value
202 sqrtss,212 sqrtss,
203 /// Square root of single precision floating-point values213 /// Subtract packed single-precision floating-point values
214 subps,
215 /// Subtract scalar single-precision floating-point values
204 subss,216 subss,
205 /// Unordered compare scalar single-precision floating-point values217 /// Unordered compare scalar single-precision floating-point values
206 ucomiss,218 ucomiss,
207 /// Bitwise logical xor of packed single precision floating-point values219 /// Bitwise logical xor of packed single precision floating-point values
208 xorps,220 xorps,
209221
210 /// Add double precision floating point values222 /// Add packed double-precision floating-point values
223 addpd,
224 /// Add scalar double-precision floating-point values
211 addsd,225 addsd,
212 /// Bitwise logical and not of packed double precision floating-point values226 /// Bitwise logical and not of packed double precision floating-point values
213 andnpd,227 andnpd,
...@@ -221,14 +235,22 @@ pub const Inst = struct {...@@ -221,14 +235,22 @@ pub const Inst = struct {
221 cvtsi2sd,235 cvtsi2sd,
222 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value236 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value
223 cvtss2sd,237 cvtss2sd,
238 /// Divide packed double-precision floating-point values
239 divpd,
224 /// Divide scalar double-precision floating-point values240 /// Divide scalar double-precision floating-point values
225 divsd,241 divsd,
226 /// Return maximum double-precision floating-point value242 /// Maximum of packed double-precision floating-point values
243 maxpd,
244 /// Maximum of scalar double-precision floating-point values
227 maxsd,245 maxsd,
228 /// Return minimum double-precision floating-point value246 /// Minimum of packed double-precision floating-point values
247 minpd,
248 /// Minimum of scalar double-precision floating-point values
229 minsd,249 minsd,
230 /// Move scalar double-precision floating-point value250 /// Move scalar double-precision floating-point value
231 movsd,251 movsd,
252 /// Multiply packed double-precision floating-point values
253 mulpd,
232 /// Multiply scalar double-precision floating-point values254 /// Multiply scalar double-precision floating-point values
233 mulsd,255 mulsd,
234 /// Bitwise logical or of packed double precision floating-point values256 /// Bitwise logical or of packed double precision floating-point values
...@@ -263,6 +285,8 @@ pub const Inst = struct {...@@ -263,6 +285,8 @@ pub const Inst = struct {
263 sqrtpd,285 sqrtpd,
264 /// Square root of scalar double precision floating-point value286 /// Square root of scalar double precision floating-point value
265 sqrtsd,287 sqrtsd,
288 /// Subtract packed double-precision floating-point values
289 subpd,
266 /// Subtract scalar double-precision floating-point values290 /// Subtract scalar double-precision floating-point values
267 subsd,291 subsd,
268 /// Unordered compare scalar double-precision floating-point values292 /// Unordered compare scalar double-precision floating-point values
...@@ -277,11 +301,23 @@ pub const Inst = struct {...@@ -277,11 +301,23 @@ pub const Inst = struct {
277 /// Replicate single floating-point values301 /// Replicate single floating-point values
278 movsldup,302 movsldup,
279303
280 /// Round scalar double-precision floating-point values304 /// Round packed double-precision floating-point values
305 roundpd,
306 /// Round packed single-precision floating-point values
307 roundps,
308 /// Round scalar double-precision floating-point value
281 roundsd,309 roundsd,
282 /// Round scalar single-precision floating-point values310 /// Round scalar single-precision floating-point value
283 roundss,311 roundss,
284312
313 /// Add packed double-precision floating-point values
314 vaddpd,
315 /// Add packed single-precision floating-point values
316 vaddps,
317 /// Add scalar double-precision floating-point values
318 vaddsd,
319 /// Add scalar single-precision floating-point values
320 vaddss,
285 /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value321 /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value
286 vcvtsd2ss,322 vcvtsd2ss,
287 /// Convert doubleword integer to scalar double-precision floating-point value323 /// Convert doubleword integer to scalar double-precision floating-point value
...@@ -290,6 +326,30 @@ pub const Inst = struct {...@@ -290,6 +326,30 @@ pub const Inst = struct {
290 vcvtsi2ss,326 vcvtsi2ss,
291 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value327 /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value
292 vcvtss2sd,328 vcvtss2sd,
329 /// Divide packed double-precision floating-point values
330 vdivpd,
331 /// Divide packed single-precision floating-point values
332 vdivps,
333 /// Divide scalar double-precision floating-point values
334 vdivsd,
335 /// Divide scalar single-precision floating-point values
336 vdivss,
337 /// Maximum of packed double-precision floating-point values
338 vmaxpd,
339 /// Maximum of packed single-precision floating-point values
340 vmaxps,
341 /// Maximum of scalar double-precision floating-point values
342 vmaxsd,
343 /// Maximum of scalar single-precision floating-point values
344 vmaxss,
345 /// Minimum of packed double-precision floating-point values
346 vminpd,
347 /// Minimum of packed single-precision floating-point values
348 vminps,
349 /// Minimum of scalar double-precision floating-point values
350 vminsd,
351 /// Minimum of scalar single-precision floating-point values
352 vminss,
293 /// Move aligned packed double-precision floating-point values353 /// Move aligned packed double-precision floating-point values
294 vmovapd,354 vmovapd,
295 /// Move aligned packed single-precision floating-point values355 /// Move aligned packed single-precision floating-point values
...@@ -308,6 +368,14 @@ pub const Inst = struct {...@@ -308,6 +368,14 @@ pub const Inst = struct {
308 vmovupd,368 vmovupd,
309 /// Move unaligned packed single-precision floating-point values369 /// Move unaligned packed single-precision floating-point values
310 vmovups,370 vmovups,
371 /// Multiply packed double-precision floating-point values
372 vmulpd,
373 /// Multiply packed single-precision floating-point values
374 vmulps,
375 /// Multiply scalar double-precision floating-point values
376 vmulsd,
377 /// Multiply scalar single-precision floating-point values
378 vmulss,
311 /// Extract word379 /// Extract word
312 vpextrw,380 vpextrw,
313 /// Insert word381 /// Insert word
...@@ -338,6 +406,14 @@ pub const Inst = struct {...@@ -338,6 +406,14 @@ pub const Inst = struct {
338 vpunpcklqdq,406 vpunpcklqdq,
339 /// Unpack low data407 /// Unpack low data
340 vpunpcklwd,408 vpunpcklwd,
409 /// Round packed double-precision floating-point values
410 vroundpd,
411 /// Round packed single-precision floating-point values
412 vroundps,
413 /// Round scalar double-precision floating-point value
414 vroundsd,
415 /// Round scalar single-precision floating-point value
416 vroundss,
341 /// Square root of packed double-precision floating-point value417 /// Square root of packed double-precision floating-point value
342 vsqrtpd,418 vsqrtpd,
343 /// Square root of packed single-precision floating-point value419 /// Square root of packed single-precision floating-point value
...@@ -346,6 +422,14 @@ pub const Inst = struct {...@@ -346,6 +422,14 @@ pub const Inst = struct {
346 vsqrtsd,422 vsqrtsd,
347 /// Square root of scalar single-precision floating-point value423 /// Square root of scalar single-precision floating-point value
348 vsqrtss,424 vsqrtss,
425 /// Subtract packed double-precision floating-point values
426 vsubpd,
427 /// Subtract packed single-precision floating-point values
428 vsubps,
429 /// Subtract scalar double-precision floating-point values
430 vsubsd,
431 /// Subtract scalar single-precision floating-point values
432 vsubss,
349433
350 /// Convert 16-bit floating-point values to single-precision floating-point values434 /// Convert 16-bit floating-point values to single-precision floating-point values
351 vcvtph2ps,435 vcvtph2ps,
...@@ -442,6 +526,9 @@ pub const Inst = struct {...@@ -442,6 +526,9 @@ pub const Inst = struct {
442 /// Register, register, register operands.526 /// Register, register, register operands.
443 /// Uses `rrr` payload.527 /// Uses `rrr` payload.
444 rrr,528 rrr,
529 /// Register, register, register, immediate (byte) operands.
530 /// Uses `rrri` payload.
531 rrri,
445 /// Register, register, immediate (sign-extended) operands.532 /// Register, register, immediate (sign-extended) operands.
446 /// Uses `rri` payload.533 /// Uses `rri` payload.
447 rri_s,534 rri_s,
...@@ -625,6 +712,12 @@ pub const Inst = struct {...@@ -625,6 +712,12 @@ pub const Inst = struct {
625 r2: Register,712 r2: Register,
626 r3: Register,713 r3: Register,
627 },714 },
715 rrri: struct {
716 r1: Register,
717 r2: Register,
718 r3: Register,
719 i: u8,
720 },
628 rri: struct {721 rri: struct {
629 r1: Register,722 r1: Register,
630 r2: Register,723 r2: Register,
src/arch/x86_64/encodings.zig+100-1
...@@ -837,6 +837,8 @@ pub const table = [_]Entry{...@@ -837,6 +837,8 @@ pub const table = [_]Entry{
837 .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none },837 .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none },
838838
839 // SSE839 // SSE
840 .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse },
841
840 .{ .addss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .none, .sse },842 .{ .addss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .none, .sse },
841843
842 .{ .andnps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x55 }, 0, .none, .sse },844 .{ .andnps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x55 }, 0, .none, .sse },
...@@ -848,10 +850,16 @@ pub const table = [_]Entry{...@@ -848,10 +850,16 @@ pub const table = [_]Entry{
848 .{ .cvtsi2ss, .rm, &.{ .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .none, .sse },850 .{ .cvtsi2ss, .rm, &.{ .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .none, .sse },
849 .{ .cvtsi2ss, .rm, &.{ .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .long, .sse },851 .{ .cvtsi2ss, .rm, &.{ .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .long, .sse },
850852
853 .{ .divps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5e }, 0, .none, .sse },
854
851 .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse },855 .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse },
852856
857 .{ .maxps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .none, .sse },
858
853 .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .none, .sse },859 .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .none, .sse },
854860
861 .{ .minps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5d }, 0, .none, .sse },
862
855 .{ .minss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .none, .sse },863 .{ .minss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .none, .sse },
856864
857 .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse },865 .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse },
...@@ -863,10 +871,14 @@ pub const table = [_]Entry{...@@ -863,10 +871,14 @@ pub const table = [_]Entry{
863 .{ .movups, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x10 }, 0, .none, .sse },871 .{ .movups, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x10 }, 0, .none, .sse },
864 .{ .movups, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x11 }, 0, .none, .sse },872 .{ .movups, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x11 }, 0, .none, .sse },
865873
874 .{ .mulps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x59 }, 0, .none, .sse },
875
866 .{ .mulss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .none, .sse },876 .{ .mulss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .none, .sse },
867877
868 .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse },878 .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse },
869879
880 .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse },
881
870 .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse },882 .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse },
871883
872 .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse },884 .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse },
...@@ -878,6 +890,8 @@ pub const table = [_]Entry{...@@ -878,6 +890,8 @@ pub const table = [_]Entry{
878 .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse },890 .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse },
879891
880 // SSE2892 // SSE2
893 .{ .addpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .none, .sse2 },
894
881 .{ .addsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .none, .sse2 },895 .{ .addsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .none, .sse2 },
882896
883 .{ .andnpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x55 }, 0, .none, .sse2 },897 .{ .andnpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x55 }, 0, .none, .sse2 },
...@@ -893,10 +907,16 @@ pub const table = [_]Entry{...@@ -893,10 +907,16 @@ pub const table = [_]Entry{
893907
894 .{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .none, .sse2 },908 .{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .none, .sse2 },
895909
910 .{ .divpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .none, .sse2 },
911
896 .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 },912 .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 },
897913
914 .{ .maxpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .none, .sse2 },
915
898 .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .none, .sse2 },916 .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .none, .sse2 },
899917
918 .{ .minpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5d }, 0, .none, .sse2 },
919
900 .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .none, .sse2 },920 .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .none, .sse2 },
901921
902 .{ .movapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .none, .sse2 },922 .{ .movapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .none, .sse2 },
...@@ -914,6 +934,8 @@ pub const table = [_]Entry{...@@ -914,6 +934,8 @@ pub const table = [_]Entry{
914 .{ .movupd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x10 }, 0, .none, .sse2 },934 .{ .movupd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x10 }, 0, .none, .sse2 },
915 .{ .movupd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x11 }, 0, .none, .sse2 },935 .{ .movupd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x11 }, 0, .none, .sse2 },
916936
937 .{ .mulpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x59 }, 0, .none, .sse2 },
938
917 .{ .mulsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .none, .sse2 },939 .{ .mulsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .none, .sse2 },
918940
919 .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 },941 .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 },
...@@ -947,6 +969,8 @@ pub const table = [_]Entry{...@@ -947,6 +969,8 @@ pub const table = [_]Entry{
947969
948 .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 },970 .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 },
949971
972 .{ .subpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5c }, 0, .none, .sse2 },
973
950 .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .none, .sse2 },974 .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .none, .sse2 },
951975
952 .{ .movsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .none, .sse2 },976 .{ .movsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .none, .sse2 },
...@@ -966,10 +990,25 @@ pub const table = [_]Entry{...@@ -966,10 +990,25 @@ pub const table = [_]Entry{
966 // SSE4.1990 // SSE4.1
967 .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 },991 .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 },
968992
969 .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .none, .sse4_1 },993 .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 },
994
995 .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 },
996
970 .{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .none, .sse4_1 },997 .{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .none, .sse4_1 },
971998
999 .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .none, .sse4_1 },
1000
972 // AVX1001 // AVX
1002 .{ .vaddpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_128_wig, .avx },
1003 .{ .vaddpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_256_wig, .avx },
1004
1005 .{ .vaddps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .vex_128_wig, .avx },
1006 .{ .vaddps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x58 }, 0, .vex_256_wig, .avx },
1007
1008 .{ .vaddsd, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx },
1009
1010 .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx },
1011
973 .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },1012 .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },
9741013
975 .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx },1014 .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx },
...@@ -980,6 +1019,36 @@ pub const table = [_]Entry{...@@ -980,6 +1019,36 @@ pub const table = [_]Entry{
9801019
981 .{ .vcvtss2sd, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },1020 .{ .vcvtss2sd, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx },
9821021
1022 .{ .vdivpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_128_wig, .avx },
1023 .{ .vdivpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_256_wig, .avx },
1024
1025 .{ .vdivps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x5e }, 0, .vex_128_wig, .avx },
1026 .{ .vdivps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x5e }, 0, .vex_256_wig, .avx },
1027
1028 .{ .vdivsd, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .vex_lig_wig, .avx },
1029
1030 .{ .vdivss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .vex_lig_wig, .avx },
1031
1032 .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx },
1033 .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx },
1034
1035 .{ .vmaxps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .vex_128_wig, .avx },
1036 .{ .vmaxps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x5f }, 0, .vex_256_wig, .avx },
1037
1038 .{ .vmaxsd, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .vex_lig_wig, .avx },
1039
1040 .{ .vmaxss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .vex_lig_wig, .avx },
1041
1042 .{ .vminpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5d }, 0, .vex_128_wig, .avx },
1043 .{ .vminpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5d }, 0, .vex_256_wig, .avx },
1044
1045 .{ .vminps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x5d }, 0, .vex_128_wig, .avx },
1046 .{ .vminps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x5d }, 0, .vex_256_wig, .avx },
1047
1048 .{ .vminsd, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .vex_lig_wig, .avx },
1049
1050 .{ .vminss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .vex_lig_wig, .avx },
1051
983 .{ .vmovapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .vex_128_wig, .avx },1052 .{ .vmovapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .vex_128_wig, .avx },
984 .{ .vmovapd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x29 }, 0, .vex_128_wig, .avx },1053 .{ .vmovapd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x29 }, 0, .vex_128_wig, .avx },
985 .{ .vmovapd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x28 }, 0, .vex_256_wig, .avx },1054 .{ .vmovapd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x28 }, 0, .vex_256_wig, .avx },
...@@ -1019,6 +1088,16 @@ pub const table = [_]Entry{...@@ -1019,6 +1088,16 @@ pub const table = [_]Entry{
1019 .{ .vmovups, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x0f, 0x10 }, 0, .vex_256_wig, .avx },1088 .{ .vmovups, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x0f, 0x10 }, 0, .vex_256_wig, .avx },
1020 .{ .vmovups, .mr, &.{ .ymm_m256, .ymm }, &.{ 0x0f, 0x11 }, 0, .vex_256_wig, .avx },1089 .{ .vmovups, .mr, &.{ .ymm_m256, .ymm }, &.{ 0x0f, 0x11 }, 0, .vex_256_wig, .avx },
10211090
1091 .{ .vmulpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x59 }, 0, .vex_128_wig, .avx },
1092 .{ .vmulpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x59 }, 0, .vex_256_wig, .avx },
1093
1094 .{ .vmulps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x59 }, 0, .vex_128_wig, .avx },
1095 .{ .vmulps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x59 }, 0, .vex_256_wig, .avx },
1096
1097 .{ .vmulsd, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx },
1098
1099 .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx },
1100
1022 .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx },1101 .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx },
1023 .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx },1102 .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx },
10241103
...@@ -1041,6 +1120,16 @@ pub const table = [_]Entry{...@@ -1041,6 +1120,16 @@ pub const table = [_]Entry{
1041 .{ .vpunpckldq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_128_wig, .avx },1120 .{ .vpunpckldq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_128_wig, .avx },
1042 .{ .vpunpcklqdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_128_wig, .avx },1121 .{ .vpunpcklqdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_128_wig, .avx },
10431122
1123 .{ .vroundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .vex_128_wig, .avx },
1124 .{ .vroundpd, .rmi, &.{ .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .vex_256_wig, .avx },
1125
1126 .{ .vroundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .vex_128_wig, .avx },
1127 .{ .vroundps, .rmi, &.{ .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .vex_256_wig, .avx },
1128
1129 .{ .vroundsd, .rvmi, &.{ .xmm, .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .vex_lig_wig, .avx },
1130
1131 .{ .vroundss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .vex_lig_wig, .avx },
1132
1044 .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx },1133 .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx },
1045 .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx },1134 .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx },
10461135
...@@ -1051,6 +1140,16 @@ pub const table = [_]Entry{...@@ -1051,6 +1140,16 @@ pub const table = [_]Entry{
10511140
1052 .{ .vsqrtss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .vex_lig_wig, .avx },1141 .{ .vsqrtss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .vex_lig_wig, .avx },
10531142
1143 .{ .vsubpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5c }, 0, .vex_128_wig, .avx },
1144 .{ .vsubpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5c }, 0, .vex_256_wig, .avx },
1145
1146 .{ .vsubps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .vex_128_wig, .avx },
1147 .{ .vsubps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x5c }, 0, .vex_256_wig, .avx },
1148
1149 .{ .vsubsd, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .vex_lig_wig, .avx },
1150
1151 .{ .vsubss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .vex_lig_wig, .avx },
1152
1054 // F16C1153 // F16C
1055 .{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c },1154 .{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c },
1056 .{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c },1155 .{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c },