| author | |
| committer | |
| log | 057139fda575e0e6038b821256a45669cd70a073 |
| tree | 38b4efefb2f63fdb4a6c369caf38d025810d3dd9 |
| parent | ea957c4cff77f045108863cb5552b3511cb455c1 |
5 files changed, 651 insertions(+), 290 deletions(-)
src/arch/x86_64/CodeGen.zig+377-265| ... | ... | @@ -1176,6 +1176,21 @@ fn asmRegisterRegisterRegister( |
| 1176 | 1176 | }); |
| 1177 | 1177 | } |
| 1178 | 1178 | |
| 1179 | fn 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 | ||
| 1179 | 1194 | fn asmRegisterRegisterImmediate( |
| 1180 | 1195 | self: *Self, |
| 1181 | 1196 | tag: Mir.Inst.Tag, |
| ... | ... | @@ -2310,20 +2325,31 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2310 | 2325 | }), |
| 2311 | 2326 | } |
| 2312 | 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 | 2329 | .vcvtsd2ss, |
| 2315 | 2330 | dst_reg, |
| 2316 | 2331 | dst_reg, |
| 2317 | src_mcv.getReg().?.to128(), | |
| 2318 | ) else try self.asmRegisterRegisterMemory( | |
| 2332 | src_mcv.mem(.qword), | |
| 2333 | ) else try self.asmRegisterRegisterRegister( | |
| 2319 | 2334 | .vcvtsd2ss, |
| 2320 | 2335 | dst_reg, |
| 2321 | 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 | 2344 | src_mcv.mem(.qword), |
| 2323 | ) else if (src_mcv.isRegister()) | |
| 2324 | try self.asmRegisterRegister(.cvtsd2ss, dst_reg, src_mcv.getReg().?.to128()) | |
| 2325 | else | |
| 2326 | try self.asmRegisterMemory(.cvtsd2ss, dst_reg, src_mcv.mem(.qword)); | |
| 2345 | ) else try self.asmRegisterRegister( | |
| 2346 | .cvtsd2ss, | |
| 2347 | dst_reg, | |
| 2348 | (if (src_mcv.isRegister()) | |
| 2349 | src_mcv.getReg().? | |
| 2350 | else | |
| 2351 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | |
| 2352 | ); | |
| 2327 | 2353 | } else return self.fail("TODO implement airFptrunc from {} to {}", .{ |
| 2328 | 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 | 2386 | }), |
| 2361 | 2387 | } |
| 2362 | 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 | 2390 | .vcvtss2sd, |
| 2365 | 2391 | dst_reg, |
| 2366 | 2392 | dst_reg, |
| 2367 | src_mcv.getReg().?.to128(), | |
| 2368 | ) else try self.asmRegisterRegisterMemory( | |
| 2393 | src_mcv.mem(.dword), | |
| 2394 | ) else try self.asmRegisterRegisterRegister( | |
| 2369 | 2395 | .vcvtss2sd, |
| 2370 | 2396 | dst_reg, |
| 2371 | 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 | 2405 | src_mcv.mem(.dword), |
| 2373 | ) else if (src_mcv.isRegister()) | |
| 2374 | try self.asmRegisterRegister(.cvtss2sd, dst_reg, src_mcv.getReg().?.to128()) | |
| 2375 | else | |
| 2376 | try self.asmRegisterMemory(.cvtss2sd, dst_reg, src_mcv.mem(.dword)); | |
| 2406 | ) else try self.asmRegisterRegister( | |
| 2407 | .cvtss2sd, | |
| 2408 | dst_reg, | |
| 2409 | (if (src_mcv.isRegister()) | |
| 2410 | src_mcv.getReg().? | |
| 2411 | else | |
| 2412 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | |
| 2413 | ); | |
| 2377 | 2414 | } else return self.fail("TODO implement airFpext from {} to {}", .{ |
| 2378 | 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 | 4569 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 4533 | 4570 | |
| 4534 | 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 | 4573 | .Float => switch (ty.floatBits(self.target.*)) { |
| 4537 | 4574 | 16 => if (self.hasFeature(.f16c)) { |
| 4538 | 4575 | const mat_src_reg = if (src_mcv.isRegister()) |
| ... | ... | @@ -4558,11 +4595,14 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4558 | 4595 | .Float => switch (ty.childType().floatBits(self.target.*)) { |
| 4559 | 4596 | 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) { |
| 4560 | 4597 | 1 => { |
| 4561 | const mat_src_reg = if (src_mcv.isRegister()) | |
| 4562 | src_mcv.getReg().? | |
| 4563 | else | |
| 4564 | try self.copyToTmpRegister(ty, src_mcv); | |
| 4565 | try self.asmRegisterRegister(.vcvtph2ps, dst_reg, mat_src_reg.to128()); | |
| 4598 | try self.asmRegisterRegister( | |
| 4599 | .vcvtph2ps, | |
| 4600 | dst_reg, | |
| 4601 | (if (src_mcv.isRegister()) | |
| 4602 | src_mcv.getReg().? | |
| 4603 | else | |
| 4604 | try self.copyToTmpRegister(ty, src_mcv)).to128(), | |
| 4605 | ); | |
| 4566 | 4606 | try self.asmRegisterRegisterRegister(.vsqrtss, dst_reg, dst_reg, dst_reg); |
| 4567 | 4607 | try self.asmRegisterRegisterImmediate( |
| 4568 | 4608 | .vcvtps2ph, |
| ... | ... | @@ -4574,16 +4614,19 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4574 | 4614 | }, |
| 4575 | 4615 | 2...8 => { |
| 4576 | 4616 | const wide_reg = registerAlias(dst_reg, abi_size * 2); |
| 4577 | if (src_mcv.isRegister()) try self.asmRegisterRegister( | |
| 4578 | .vcvtph2ps, | |
| 4579 | wide_reg, | |
| 4580 | src_mcv.getReg().?.to128(), | |
| 4581 | ) else try self.asmRegisterMemory( | |
| 4617 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | |
| 4582 | 4618 | .vcvtph2ps, |
| 4583 | 4619 | wide_reg, |
| 4584 | 4620 | src_mcv.mem(Memory.PtrSize.fromSize( |
| 4585 | 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 | 4631 | try self.asmRegisterRegister(.vsqrtps, wide_reg, wide_reg); |
| 4589 | 4632 | try self.asmRegisterRegisterImmediate( |
| ... | ... | @@ -4617,26 +4660,32 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4617 | 4660 | })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{ |
| 4618 | 4661 | ty.fmt(self.bin_file.options.module.?), |
| 4619 | 4662 | }); |
| 4620 | switch (tag) { | |
| 4621 | .vsqrtss, .vsqrtsd => if (src_mcv.isRegister()) try self.asmRegisterRegisterRegister( | |
| 4622 | tag, | |
| 4663 | switch (mir_tag) { | |
| 4664 | .vsqrtss, .vsqrtsd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | |
| 4665 | mir_tag, | |
| 4623 | 4666 | dst_reg, |
| 4624 | 4667 | dst_reg, |
| 4625 | registerAlias(src_mcv.getReg().?, abi_size), | |
| 4626 | ) else try self.asmRegisterRegisterMemory( | |
| 4627 | tag, | |
| 4668 | src_mcv.mem(Memory.PtrSize.fromSize(abi_size)), | |
| 4669 | ) else try self.asmRegisterRegisterRegister( | |
| 4670 | mir_tag, | |
| 4628 | 4671 | dst_reg, |
| 4629 | 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( | |
| 4633 | tag, | |
| 4634 | dst_reg, | |
| 4635 | registerAlias(src_mcv.getReg().?, abi_size), | |
| 4636 | ) else try self.asmRegisterMemory( | |
| 4637 | tag, | |
| 4678 | else => if (src_mcv.isMemory()) try self.asmRegisterMemory( | |
| 4679 | mir_tag, | |
| 4638 | 4680 | dst_reg, |
| 4639 | 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 | 4691 | break :result dst_mcv; |
| ... | ... | @@ -5800,25 +5849,22 @@ fn genMulDivBinOp( |
| 5800 | 5849 | } |
| 5801 | 5850 | } |
| 5802 | 5851 | |
| 5803 | /// Result is always a register. | |
| 5804 | 5852 | fn genBinOp( |
| 5805 | 5853 | self: *Self, |
| 5806 | 5854 | maybe_inst: ?Air.Inst.Index, |
| 5807 | tag: Air.Inst.Tag, | |
| 5855 | air_tag: Air.Inst.Tag, | |
| 5808 | 5856 | lhs_air: Air.Inst.Ref, |
| 5809 | 5857 | rhs_air: Air.Inst.Ref, |
| 5810 | 5858 | ) !MCValue { |
| 5811 | const lhs = try self.resolveInst(lhs_air); | |
| 5812 | const rhs = try self.resolveInst(rhs_air); | |
| 5859 | const lhs_mcv = try self.resolveInst(lhs_air); | |
| 5860 | const rhs_mcv = try self.resolveInst(rhs_air); | |
| 5813 | 5861 | const lhs_ty = self.air.typeOf(lhs_air); |
| 5814 | 5862 | const rhs_ty = self.air.typeOf(rhs_air); |
| 5815 | if (lhs_ty.zigTypeTag() == .Vector) { | |
| 5816 | return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmt(self.bin_file.options.module.?)}); | |
| 5817 | } | |
| 5863 | const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*)); | |
| 5818 | 5864 | |
| 5819 | switch (lhs) { | |
| 5865 | switch (lhs_mcv) { | |
| 5820 | 5866 | .immediate => |imm| switch (imm) { |
| 5821 | 0 => switch (tag) { | |
| 5867 | 0 => switch (air_tag) { | |
| 5822 | 5868 | .sub, .subwrap => return self.genUnOp(maybe_inst, .neg, rhs_air), |
| 5823 | 5869 | else => {}, |
| 5824 | 5870 | }, |
| ... | ... | @@ -5827,9 +5873,10 @@ fn genBinOp( |
| 5827 | 5873 | else => {}, |
| 5828 | 5874 | } |
| 5829 | 5875 | |
| 5830 | const is_commutative = switch (tag) { | |
| 5876 | const is_commutative = switch (air_tag) { | |
| 5831 | 5877 | .add, |
| 5832 | 5878 | .addwrap, |
| 5879 | .mul, | |
| 5833 | 5880 | .bool_or, |
| 5834 | 5881 | .bit_or, |
| 5835 | 5882 | .bool_and, |
| ... | ... | @@ -5841,48 +5888,42 @@ fn genBinOp( |
| 5841 | 5888 | |
| 5842 | 5889 | else => false, |
| 5843 | 5890 | }; |
| 5844 | const dst_mem_ok = switch (tag) { | |
| 5845 | .add, | |
| 5846 | .addwrap, | |
| 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, | |
| 5891 | const vec_op = switch (lhs_ty.zigTypeTag()) { | |
| 5892 | else => false, | |
| 5893 | .Float, .Vector => true, | |
| 5857 | 5894 | }; |
| 5858 | 5895 | |
| 5859 | const lhs_lock: ?RegisterLock = switch (lhs) { | |
| 5896 | const lhs_lock: ?RegisterLock = switch (lhs_mcv) { | |
| 5860 | 5897 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 5861 | 5898 | else => null, |
| 5862 | 5899 | }; |
| 5863 | 5900 | defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 5864 | 5901 | |
| 5865 | const rhs_lock: ?RegisterLock = switch (rhs) { | |
| 5902 | const rhs_lock: ?RegisterLock = switch (rhs_mcv) { | |
| 5866 | 5903 | .register => |reg| self.register_manager.lockReg(reg), |
| 5867 | 5904 | else => null, |
| 5868 | 5905 | }; |
| 5869 | 5906 | defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 5870 | 5907 | |
| 5871 | var flipped: bool = false; | |
| 5908 | var flipped = false; | |
| 5909 | var copied_to_dst = true; | |
| 5872 | 5910 | const dst_mcv: MCValue = dst: { |
| 5873 | 5911 | if (maybe_inst) |inst| { |
| 5874 | if ((dst_mem_ok or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) { | |
| 5875 | break :dst lhs; | |
| 5912 | if ((!vec_op or lhs_mcv.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs_mcv)) { | |
| 5913 | break :dst lhs_mcv; | |
| 5876 | 5914 | } |
| 5877 | if (is_commutative and (dst_mem_ok or rhs.isRegister()) and | |
| 5878 | self.reuseOperand(inst, rhs_air, 1, rhs)) | |
| 5915 | if (is_commutative and (!vec_op or rhs_mcv.isRegister()) and | |
| 5916 | self.reuseOperand(inst, rhs_air, 1, rhs_mcv)) | |
| 5879 | 5917 | { |
| 5880 | 5918 | flipped = true; |
| 5881 | break :dst rhs; | |
| 5919 | break :dst rhs_mcv; | |
| 5882 | 5920 | } |
| 5883 | 5921 | } |
| 5884 | 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 | 5927 | break :dst dst_mcv; |
| 5887 | 5928 | }; |
| 5888 | 5929 | const dst_lock: ?RegisterLock = switch (dst_mcv) { |
| ... | ... | @@ -5891,160 +5932,47 @@ fn genBinOp( |
| 5891 | 5932 | }; |
| 5892 | 5933 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5893 | 5934 | |
| 5894 | const src_mcv = if (flipped) lhs else rhs; | |
| 5895 | switch (tag) { | |
| 5896 | .add, | |
| 5897 | .addwrap, | |
| 5898 | => try self.genBinOpMir(switch (lhs_ty.zigTypeTag()) { | |
| 5899 | else => .add, | |
| 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), | |
| 5935 | const src_mcv = if (flipped) lhs_mcv else rhs_mcv; | |
| 5936 | if (!vec_op) { | |
| 5937 | switch (air_tag) { | |
| 5938 | .add, | |
| 5939 | .addwrap, | |
| 5940 | => try self.genBinOpMir(.add, lhs_ty, dst_mcv, src_mcv), | |
| 5964 | 5941 | |
| 5965 | .div_float, | |
| 5966 | .div_exact, | |
| 5967 | .div_trunc, | |
| 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 | }, | |
| 5942 | .sub, | |
| 5943 | .subwrap, | |
| 5944 | => try self.genBinOpMir(.sub, lhs_ty, dst_mcv, src_mcv), | |
| 6016 | 5945 | |
| 6017 | .ptr_add, | |
| 6018 | .ptr_sub, | |
| 6019 | => { | |
| 6020 | const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv); | |
| 6021 | const tmp_mcv = MCValue{ .register = tmp_reg }; | |
| 6022 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | |
| 6023 | defer self.register_manager.unlockReg(tmp_lock); | |
| 5946 | .ptr_add, | |
| 5947 | .ptr_sub, | |
| 5948 | => { | |
| 5949 | const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv); | |
| 5950 | const tmp_mcv = MCValue{ .register = tmp_reg }; | |
| 5951 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | |
| 5952 | defer self.register_manager.unlockReg(tmp_lock); | |
| 6024 | 5953 | |
| 6025 | const elem_size = lhs_ty.elemType2().abiSize(self.target.*); | |
| 6026 | try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size }); | |
| 6027 | try self.genBinOpMir(switch (tag) { | |
| 6028 | .ptr_add => .add, | |
| 6029 | .ptr_sub => .sub, | |
| 6030 | else => unreachable, | |
| 6031 | }, lhs_ty, dst_mcv, tmp_mcv); | |
| 6032 | }, | |
| 5954 | const elem_size = lhs_ty.elemType2().abiSize(self.target.*); | |
| 5955 | try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size }); | |
| 5956 | try self.genBinOpMir(switch (air_tag) { | |
| 5957 | .ptr_add => .add, | |
| 5958 | .ptr_sub => .sub, | |
| 5959 | else => unreachable, | |
| 5960 | }, lhs_ty, dst_mcv, tmp_mcv); | |
| 5961 | }, | |
| 6033 | 5962 | |
| 6034 | .bool_or, | |
| 6035 | .bit_or, | |
| 6036 | => try self.genBinOpMir(.@"or", lhs_ty, dst_mcv, src_mcv), | |
| 5963 | .bool_or, | |
| 5964 | .bit_or, | |
| 5965 | => try self.genBinOpMir(.@"or", lhs_ty, dst_mcv, src_mcv), | |
| 6037 | 5966 | |
| 6038 | .bool_and, | |
| 6039 | .bit_and, | |
| 6040 | => try self.genBinOpMir(.@"and", lhs_ty, dst_mcv, src_mcv), | |
| 5967 | .bool_and, | |
| 5968 | .bit_and, | |
| 5969 | => try self.genBinOpMir(.@"and", lhs_ty, dst_mcv, src_mcv), | |
| 6041 | 5970 | |
| 6042 | .xor => try self.genBinOpMir(.xor, lhs_ty, dst_mcv, src_mcv), | |
| 5971 | .xor => try self.genBinOpMir(.xor, lhs_ty, dst_mcv, src_mcv), | |
| 6043 | 5972 | |
| 6044 | .min, | |
| 6045 | .max, | |
| 6046 | => switch (lhs_ty.zigTypeTag()) { | |
| 6047 | .Int => { | |
| 5973 | .min, | |
| 5974 | .max, | |
| 5975 | => { | |
| 6048 | 5976 | const mat_src_mcv: MCValue = if (switch (src_mcv) { |
| 6049 | 5977 | .immediate, |
| 6050 | 5978 | .eflags, |
| ... | ... | @@ -6070,12 +5998,12 @@ fn genBinOp( |
| 6070 | 5998 | |
| 6071 | 5999 | const int_info = lhs_ty.intInfo(self.target.*); |
| 6072 | 6000 | const cc: Condition = switch (int_info.signedness) { |
| 6073 | .unsigned => switch (tag) { | |
| 6001 | .unsigned => switch (air_tag) { | |
| 6074 | 6002 | .min => .a, |
| 6075 | 6003 | .max => .b, |
| 6076 | 6004 | else => unreachable, |
| 6077 | 6005 | }, |
| 6078 | .signed => switch (tag) { | |
| 6006 | .signed => switch (air_tag) { | |
| 6079 | 6007 | .min => .g, |
| 6080 | 6008 | .max => .l, |
| 6081 | 6009 | else => unreachable, |
| ... | ... | @@ -6134,26 +6062,222 @@ fn genBinOp( |
| 6134 | 6062 | } |
| 6135 | 6063 | try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }); |
| 6136 | 6064 | }, |
| 6137 | .Float => try self.genBinOpMir(switch (lhs_ty.floatBits(self.target.*)) { | |
| 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), | |
| 6065 | ||
| 6152 | 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 | } | |
| 6156 | 6072 | |
| 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 | 6281 | else => unreachable, |
| 6158 | 6282 | } |
| 6159 | 6283 | return dst_mcv; |
| ... | ... | @@ -6186,20 +6310,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 6186 | 6310 | .register_overflow, |
| 6187 | 6311 | .reserved_frame, |
| 6188 | 6312 | => unreachable, |
| 6189 | .register => |src_reg| switch (ty.zigTypeTag()) { | |
| 6190 | .Float => { | |
| 6191 | if (!Target.x86.featureSetHas(self.target.cpu.features, .sse)) | |
| 6192 | return self.fail("TODO genBinOpMir for {s} {} without sse", .{ | |
| 6193 | @tagName(mir_tag), ty.fmt(self.bin_file.options.module.?), | |
| 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 | }, | |
| 6313 | .register => |src_reg| try self.asmRegisterRegister( | |
| 6314 | mir_tag, | |
| 6315 | dst_alias, | |
| 6316 | registerAlias(src_reg, abi_size), | |
| 6317 | ), | |
| 6203 | 6318 | .immediate => |imm| switch (self.regBitSize(ty)) { |
| 6204 | 6319 | 8 => try self.asmRegisterImmediate( |
| 6205 | 6320 | mir_tag, |
| ... | ... | @@ -9646,7 +9761,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 9646 | 9761 | lock.* = self.register_manager.lockRegAssumeUnused(reg); |
| 9647 | 9762 | } |
| 9648 | 9763 | |
| 9649 | const tag = if (@as( | |
| 9764 | const mir_tag = if (@as( | |
| 9650 | 9765 | ?Mir.Inst.Tag, |
| 9651 | 9766 | if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 })) |
| 9652 | 9767 | switch (ty.zigTypeTag()) { |
| ... | ... | @@ -9741,20 +9856,17 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 9741 | 9856 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); |
| 9742 | 9857 | const mop1_reg = registerAlias(mops[0].getReg().?, abi_size); |
| 9743 | 9858 | const mop2_reg = registerAlias(mops[1].getReg().?, abi_size); |
| 9744 | if (mops[2].isRegister()) | |
| 9745 | try self.asmRegisterRegisterRegister( | |
| 9746 | tag, | |
| 9747 | mop1_reg, | |
| 9748 | mop2_reg, | |
| 9749 | registerAlias(mops[2].getReg().?, abi_size), | |
| 9750 | ) | |
| 9751 | else | |
| 9752 | try self.asmRegisterRegisterMemory( | |
| 9753 | tag, | |
| 9754 | mop1_reg, | |
| 9755 | mop2_reg, | |
| 9756 | mops[2].mem(Memory.PtrSize.fromSize(abi_size)), | |
| 9757 | ); | |
| 9859 | if (mops[2].isRegister()) try self.asmRegisterRegisterRegister( | |
| 9860 | mir_tag, | |
| 9861 | mop1_reg, | |
| 9862 | mop2_reg, | |
| 9863 | registerAlias(mops[2].getReg().?, abi_size), | |
| 9864 | ) else try self.asmRegisterRegisterMemory( | |
| 9865 | mir_tag, | |
| 9866 | mop1_reg, | |
| 9867 | mop2_reg, | |
| 9868 | mops[2].mem(Memory.PtrSize.fromSize(abi_size)), | |
| 9869 | ); | |
| 9758 | 9870 | return self.finishAir(inst, mops[0], ops); |
| 9759 | 9871 | } |
| 9760 | 9872 |
src/arch/x86_64/Encoding.zig+21-13| ... | ... | @@ -262,61 +262,69 @@ pub const Mnemonic = enum { |
| 262 | 262 | // MMX |
| 263 | 263 | movd, |
| 264 | 264 | // SSE |
| 265 | addss, | |
| 265 | addps, addss, | |
| 266 | 266 | andps, |
| 267 | 267 | andnps, |
| 268 | 268 | cmpss, |
| 269 | 269 | cvtsi2ss, |
| 270 | divss, | |
| 271 | maxss, minss, | |
| 270 | divps, divss, | |
| 271 | maxps, maxss, | |
| 272 | minps, minss, | |
| 272 | 273 | movaps, movss, movups, |
| 273 | mulss, | |
| 274 | mulps, mulss, | |
| 274 | 275 | orps, |
| 275 | 276 | pextrw, pinsrw, |
| 276 | sqrtps, | |
| 277 | sqrtss, | |
| 278 | subss, | |
| 277 | sqrtps, sqrtss, | |
| 278 | subps, subss, | |
| 279 | 279 | ucomiss, |
| 280 | 280 | xorps, |
| 281 | 281 | // SSE2 |
| 282 | addsd, | |
| 282 | addpd, addsd, | |
| 283 | 283 | andpd, |
| 284 | 284 | andnpd, |
| 285 | 285 | //cmpsd, |
| 286 | 286 | cvtsd2ss, cvtsi2sd, cvtss2sd, |
| 287 | divsd, | |
| 288 | maxsd, minsd, | |
| 287 | divpd, divsd, | |
| 288 | maxpd, maxsd, | |
| 289 | minpd, minsd, | |
| 289 | 290 | movapd, |
| 290 | 291 | movq, //movd, movsd, |
| 291 | 292 | movupd, |
| 292 | mulsd, | |
| 293 | mulpd, mulsd, | |
| 293 | 294 | orpd, |
| 294 | 295 | pshufhw, pshuflw, |
| 295 | 296 | psrld, psrlq, psrlw, |
| 296 | 297 | punpckhbw, punpckhdq, punpckhqdq, punpckhwd, |
| 297 | 298 | punpcklbw, punpckldq, punpcklqdq, punpcklwd, |
| 298 | 299 | sqrtpd, sqrtsd, |
| 299 | subsd, | |
| 300 | subpd, subsd, | |
| 300 | 301 | ucomisd, |
| 301 | 302 | xorpd, |
| 302 | 303 | // SSE3 |
| 303 | 304 | movddup, movshdup, movsldup, |
| 304 | 305 | // SSE4.1 |
| 305 | roundsd, roundss, | |
| 306 | roundpd, roundps, roundsd, roundss, | |
| 306 | 307 | // AVX |
| 308 | vaddpd, vaddps, vaddsd, vaddss, | |
| 307 | 309 | vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd, |
| 310 | vdivpd, vdivps, vdivsd, vdivss, | |
| 311 | vmaxpd, vmaxps, vmaxsd, vmaxss, | |
| 312 | vminpd, vminps, vminsd, vminss, | |
| 308 | 313 | vmovapd, vmovaps, |
| 309 | 314 | vmovddup, |
| 310 | 315 | vmovsd, |
| 311 | 316 | vmovshdup, vmovsldup, |
| 312 | 317 | vmovss, |
| 313 | 318 | vmovupd, vmovups, |
| 319 | vmulpd, vmulps, vmulsd, vmulss, | |
| 314 | 320 | vpextrw, vpinsrw, |
| 315 | 321 | vpshufhw, vpshuflw, |
| 316 | 322 | vpsrld, vpsrlq, vpsrlw, |
| 317 | 323 | vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd, |
| 318 | 324 | vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd, |
| 325 | vroundpd, vroundps, vroundsd, vroundss, | |
| 319 | 326 | vsqrtpd, vsqrtps, vsqrtsd, vsqrtss, |
| 327 | vsubpd, vsubps, vsubsd, vsubss, | |
| 320 | 328 | // F16C |
| 321 | 329 | vcvtph2ps, vcvtps2ph, |
| 322 | 330 | // FMA |
src/arch/x86_64/Lower.zig+49| ... | ... | @@ -124,27 +124,34 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 124 | 124 | .xchg, |
| 125 | 125 | .xor, |
| 126 | 126 | |
| 127 | .addps, | |
| 127 | 128 | .addss, |
| 128 | 129 | .andnps, |
| 129 | 130 | .andps, |
| 130 | 131 | .cmpss, |
| 131 | 132 | .cvtsi2ss, |
| 133 | .divps, | |
| 132 | 134 | .divss, |
| 135 | .maxps, | |
| 133 | 136 | .maxss, |
| 137 | .minps, | |
| 134 | 138 | .minss, |
| 135 | 139 | .movaps, |
| 136 | 140 | .movss, |
| 137 | 141 | .movups, |
| 142 | .mulps, | |
| 138 | 143 | .mulss, |
| 139 | 144 | .orps, |
| 140 | 145 | .pextrw, |
| 141 | 146 | .pinsrw, |
| 142 | 147 | .sqrtps, |
| 143 | 148 | .sqrtss, |
| 149 | .subps, | |
| 144 | 150 | .subss, |
| 145 | 151 | .ucomiss, |
| 146 | 152 | .xorps, |
| 147 | 153 | |
| 154 | .addpd, | |
| 148 | 155 | .addsd, |
| 149 | 156 | .andnpd, |
| 150 | 157 | .andpd, |
| ... | ... | @@ -152,10 +159,14 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 152 | 159 | .cvtsd2ss, |
| 153 | 160 | .cvtsi2sd, |
| 154 | 161 | .cvtss2sd, |
| 162 | .divpd, | |
| 155 | 163 | .divsd, |
| 164 | .maxpd, | |
| 156 | 165 | .maxsd, |
| 166 | .minpd, | |
| 157 | 167 | .minsd, |
| 158 | 168 | .movsd, |
| 169 | .mulpd, | |
| 159 | 170 | .mulsd, |
| 160 | 171 | .orpd, |
| 161 | 172 | .pshufhw, |
| ... | ... | @@ -173,6 +184,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 173 | 184 | .punpcklwd, |
| 174 | 185 | .sqrtpd, |
| 175 | 186 | .sqrtsd, |
| 187 | .subpd, | |
| 176 | 188 | .subsd, |
| 177 | 189 | .ucomisd, |
| 178 | 190 | .xorpd, |
| ... | ... | @@ -181,13 +193,31 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 181 | 193 | .movshdup, |
| 182 | 194 | .movsldup, |
| 183 | 195 | |
| 196 | .roundpd, | |
| 197 | .roundps, | |
| 184 | 198 | .roundsd, |
| 185 | 199 | .roundss, |
| 186 | 200 | |
| 201 | .vaddpd, | |
| 202 | .vaddps, | |
| 203 | .vaddsd, | |
| 204 | .vaddss, | |
| 187 | 205 | .vcvtsd2ss, |
| 188 | 206 | .vcvtsi2sd, |
| 189 | 207 | .vcvtsi2ss, |
| 190 | 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 | 221 | .vmovapd, |
| 192 | 222 | .vmovaps, |
| 193 | 223 | .vmovddup, |
| ... | ... | @@ -197,6 +227,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 197 | 227 | .vmovss, |
| 198 | 228 | .vmovupd, |
| 199 | 229 | .vmovups, |
| 230 | .vmulpd, | |
| 231 | .vmulps, | |
| 232 | .vmulsd, | |
| 233 | .vmulss, | |
| 200 | 234 | .vpextrw, |
| 201 | 235 | .vpinsrw, |
| 202 | 236 | .vpshufhw, |
| ... | ... | @@ -212,10 +246,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 212 | 246 | .vpunpckldq, |
| 213 | 247 | .vpunpcklqdq, |
| 214 | 248 | .vpunpcklwd, |
| 249 | .vroundpd, | |
| 250 | .vroundps, | |
| 251 | .vroundsd, | |
| 252 | .vroundss, | |
| 215 | 253 | .vsqrtpd, |
| 216 | 254 | .vsqrtps, |
| 217 | 255 | .vsqrtsd, |
| 218 | 256 | .vsqrtss, |
| 257 | .vsubpd, | |
| 258 | .vsubps, | |
| 259 | .vsubsd, | |
| 260 | .vsubss, | |
| 219 | 261 | |
| 220 | 262 | .vcvtph2ps, |
| 221 | 263 | .vcvtps2ph, |
| ... | ... | @@ -304,6 +346,7 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { |
| 304 | 346 | .lock_mi_rip_s, |
| 305 | 347 | => Immediate.s(@bitCast(i32, i)), |
| 306 | 348 | |
| 349 | .rrri, | |
| 307 | 350 | .rri_u, |
| 308 | 351 | .ri_u, |
| 309 | 352 | .i_u, |
| ... | ... | @@ -429,6 +472,12 @@ fn mirGeneric(lower: *Lower, inst: Mir.Inst) Error!void { |
| 429 | 472 | .{ .reg = inst.data.rrr.r2 }, |
| 430 | 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 | 481 | .ri_s, .ri_u => &.{ |
| 433 | 482 | .{ .reg = inst.data.ri.r }, |
| 434 | 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 | 166 | /// Logical exclusive-or |
| 167 | 167 | xor, |
| 168 | 168 | |
| 169 | /// Add single precision floating point values | |
| 169 | /// Add packed single-precision floating-point values | |
| 170 | addps, | |
| 171 | /// Add scalar single-precision floating-point values | |
| 170 | 172 | addss, |
| 171 | 173 | /// Bitwise logical and of packed single precision floating-point values |
| 172 | 174 | andps, |
| ... | ... | @@ -176,11 +178,17 @@ pub const Inst = struct { |
| 176 | 178 | cmpss, |
| 177 | 179 | /// Convert doubleword integer to scalar single-precision floating-point value |
| 178 | 180 | cvtsi2ss, |
| 181 | /// Divide packed single-precision floating-point values | |
| 182 | divps, | |
| 179 | 183 | /// Divide scalar single-precision floating-point values |
| 180 | 184 | divss, |
| 181 | /// Return maximum single-precision floating-point value | |
| 185 | /// Maximum of packed single-precision floating-point values | |
| 186 | maxps, | |
| 187 | /// Maximum of scalar single-precision floating-point values | |
| 182 | 188 | maxss, |
| 183 | /// Return minimum single-precision floating-point value | |
| 189 | /// Minimum of packed single-precision floating-point values | |
| 190 | minps, | |
| 191 | /// Minimum of scalar single-precision floating-point values | |
| 184 | 192 | minss, |
| 185 | 193 | /// Move aligned packed single-precision floating-point values |
| 186 | 194 | movaps, |
| ... | ... | @@ -188,6 +196,8 @@ pub const Inst = struct { |
| 188 | 196 | movss, |
| 189 | 197 | /// Move unaligned packed single-precision floating-point values |
| 190 | 198 | movups, |
| 199 | /// Multiply packed single-precision floating-point values | |
| 200 | mulps, | |
| 191 | 201 | /// Multiply scalar single-precision floating-point values |
| 192 | 202 | mulss, |
| 193 | 203 | /// Bitwise logical or of packed single precision floating-point values |
| ... | ... | @@ -196,18 +206,22 @@ pub const Inst = struct { |
| 196 | 206 | pextrw, |
| 197 | 207 | /// Insert word |
| 198 | 208 | pinsrw, |
| 199 | /// Square root of scalar single precision floating-point value | |
| 209 | /// Square root of packed single-precision floating-point values | |
| 200 | 210 | sqrtps, |
| 201 | /// Subtract scalar single-precision floating-point values | |
| 211 | /// Square root of scalar single-precision floating-point value | |
| 202 | 212 | sqrtss, |
| 203 | /// Square root of single precision floating-point values | |
| 213 | /// Subtract packed single-precision floating-point values | |
| 214 | subps, | |
| 215 | /// Subtract scalar single-precision floating-point values | |
| 204 | 216 | subss, |
| 205 | 217 | /// Unordered compare scalar single-precision floating-point values |
| 206 | 218 | ucomiss, |
| 207 | 219 | /// Bitwise logical xor of packed single precision floating-point values |
| 208 | 220 | xorps, |
| 209 | 221 | |
| 210 | /// Add double precision floating point values | |
| 222 | /// Add packed double-precision floating-point values | |
| 223 | addpd, | |
| 224 | /// Add scalar double-precision floating-point values | |
| 211 | 225 | addsd, |
| 212 | 226 | /// Bitwise logical and not of packed double precision floating-point values |
| 213 | 227 | andnpd, |
| ... | ... | @@ -221,14 +235,22 @@ pub const Inst = struct { |
| 221 | 235 | cvtsi2sd, |
| 222 | 236 | /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value |
| 223 | 237 | cvtss2sd, |
| 238 | /// Divide packed double-precision floating-point values | |
| 239 | divpd, | |
| 224 | 240 | /// Divide scalar double-precision floating-point values |
| 225 | 241 | divsd, |
| 226 | /// Return maximum double-precision floating-point value | |
| 242 | /// Maximum of packed double-precision floating-point values | |
| 243 | maxpd, | |
| 244 | /// Maximum of scalar double-precision floating-point values | |
| 227 | 245 | maxsd, |
| 228 | /// Return minimum double-precision floating-point value | |
| 246 | /// Minimum of packed double-precision floating-point values | |
| 247 | minpd, | |
| 248 | /// Minimum of scalar double-precision floating-point values | |
| 229 | 249 | minsd, |
| 230 | 250 | /// Move scalar double-precision floating-point value |
| 231 | 251 | movsd, |
| 252 | /// Multiply packed double-precision floating-point values | |
| 253 | mulpd, | |
| 232 | 254 | /// Multiply scalar double-precision floating-point values |
| 233 | 255 | mulsd, |
| 234 | 256 | /// Bitwise logical or of packed double precision floating-point values |
| ... | ... | @@ -263,6 +285,8 @@ pub const Inst = struct { |
| 263 | 285 | sqrtpd, |
| 264 | 286 | /// Square root of scalar double precision floating-point value |
| 265 | 287 | sqrtsd, |
| 288 | /// Subtract packed double-precision floating-point values | |
| 289 | subpd, | |
| 266 | 290 | /// Subtract scalar double-precision floating-point values |
| 267 | 291 | subsd, |
| 268 | 292 | /// Unordered compare scalar double-precision floating-point values |
| ... | ... | @@ -277,11 +301,23 @@ pub const Inst = struct { |
| 277 | 301 | /// Replicate single floating-point values |
| 278 | 302 | movsldup, |
| 279 | 303 | |
| 280 | /// Round scalar double-precision floating-point values | |
| 304 | /// 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 | 309 | roundsd, |
| 282 | /// Round scalar single-precision floating-point values | |
| 310 | /// Round scalar single-precision floating-point value | |
| 283 | 311 | roundss, |
| 284 | 312 | |
| 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 | 321 | /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value |
| 286 | 322 | vcvtsd2ss, |
| 287 | 323 | /// Convert doubleword integer to scalar double-precision floating-point value |
| ... | ... | @@ -290,6 +326,30 @@ pub const Inst = struct { |
| 290 | 326 | vcvtsi2ss, |
| 291 | 327 | /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value |
| 292 | 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 | 353 | /// Move aligned packed double-precision floating-point values |
| 294 | 354 | vmovapd, |
| 295 | 355 | /// Move aligned packed single-precision floating-point values |
| ... | ... | @@ -308,6 +368,14 @@ pub const Inst = struct { |
| 308 | 368 | vmovupd, |
| 309 | 369 | /// Move unaligned packed single-precision floating-point values |
| 310 | 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 | 379 | /// Extract word |
| 312 | 380 | vpextrw, |
| 313 | 381 | /// Insert word |
| ... | ... | @@ -338,6 +406,14 @@ pub const Inst = struct { |
| 338 | 406 | vpunpcklqdq, |
| 339 | 407 | /// Unpack low data |
| 340 | 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 | 417 | /// Square root of packed double-precision floating-point value |
| 342 | 418 | vsqrtpd, |
| 343 | 419 | /// Square root of packed single-precision floating-point value |
| ... | ... | @@ -346,6 +422,14 @@ pub const Inst = struct { |
| 346 | 422 | vsqrtsd, |
| 347 | 423 | /// Square root of scalar single-precision floating-point value |
| 348 | 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, | |
| 349 | 433 | |
| 350 | 434 | /// Convert 16-bit floating-point values to single-precision floating-point values |
| 351 | 435 | vcvtph2ps, |
| ... | ... | @@ -442,6 +526,9 @@ pub const Inst = struct { |
| 442 | 526 | /// Register, register, register operands. |
| 443 | 527 | /// Uses `rrr` payload. |
| 444 | 528 | rrr, |
| 529 | /// Register, register, register, immediate (byte) operands. | |
| 530 | /// Uses `rrri` payload. | |
| 531 | rrri, | |
| 445 | 532 | /// Register, register, immediate (sign-extended) operands. |
| 446 | 533 | /// Uses `rri` payload. |
| 447 | 534 | rri_s, |
| ... | ... | @@ -625,6 +712,12 @@ pub const Inst = struct { |
| 625 | 712 | r2: Register, |
| 626 | 713 | r3: Register, |
| 627 | 714 | }, |
| 715 | rrri: struct { | |
| 716 | r1: Register, | |
| 717 | r2: Register, | |
| 718 | r3: Register, | |
| 719 | i: u8, | |
| 720 | }, | |
| 628 | 721 | rri: struct { |
| 629 | 722 | r1: Register, |
| 630 | 723 | r2: Register, |
src/arch/x86_64/encodings.zig+100-1| ... | ... | @@ -837,6 +837,8 @@ pub const table = [_]Entry{ |
| 837 | 837 | .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none }, |
| 838 | 838 | |
| 839 | 839 | // SSE |
| 840 | .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse }, | |
| 841 | ||
| 840 | 842 | .{ .addss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .none, .sse }, |
| 841 | 843 | |
| 842 | 844 | .{ .andnps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x55 }, 0, .none, .sse }, |
| ... | ... | @@ -848,10 +850,16 @@ pub const table = [_]Entry{ |
| 848 | 850 | .{ .cvtsi2ss, .rm, &.{ .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .none, .sse }, |
| 849 | 851 | .{ .cvtsi2ss, .rm, &.{ .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .long, .sse }, |
| 850 | 852 | |
| 853 | .{ .divps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5e }, 0, .none, .sse }, | |
| 854 | ||
| 851 | 855 | .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse }, |
| 852 | 856 | |
| 857 | .{ .maxps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .none, .sse }, | |
| 858 | ||
| 853 | 859 | .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .none, .sse }, |
| 854 | 860 | |
| 861 | .{ .minps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5d }, 0, .none, .sse }, | |
| 862 | ||
| 855 | 863 | .{ .minss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .none, .sse }, |
| 856 | 864 | |
| 857 | 865 | .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse }, |
| ... | ... | @@ -863,10 +871,14 @@ pub const table = [_]Entry{ |
| 863 | 871 | .{ .movups, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x10 }, 0, .none, .sse }, |
| 864 | 872 | .{ .movups, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x11 }, 0, .none, .sse }, |
| 865 | 873 | |
| 874 | .{ .mulps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x59 }, 0, .none, .sse }, | |
| 875 | ||
| 866 | 876 | .{ .mulss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .none, .sse }, |
| 867 | 877 | |
| 868 | 878 | .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse }, |
| 869 | 879 | |
| 880 | .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse }, | |
| 881 | ||
| 870 | 882 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, |
| 871 | 883 | |
| 872 | 884 | .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse }, |
| ... | ... | @@ -878,6 +890,8 @@ pub const table = [_]Entry{ |
| 878 | 890 | .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse }, |
| 879 | 891 | |
| 880 | 892 | // SSE2 |
| 893 | .{ .addpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .none, .sse2 }, | |
| 894 | ||
| 881 | 895 | .{ .addsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .none, .sse2 }, |
| 882 | 896 | |
| 883 | 897 | .{ .andnpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x55 }, 0, .none, .sse2 }, |
| ... | ... | @@ -893,10 +907,16 @@ pub const table = [_]Entry{ |
| 893 | 907 | |
| 894 | 908 | .{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .none, .sse2 }, |
| 895 | 909 | |
| 910 | .{ .divpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .none, .sse2 }, | |
| 911 | ||
| 896 | 912 | .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 }, |
| 897 | 913 | |
| 914 | .{ .maxpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .none, .sse2 }, | |
| 915 | ||
| 898 | 916 | .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .none, .sse2 }, |
| 899 | 917 | |
| 918 | .{ .minpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5d }, 0, .none, .sse2 }, | |
| 919 | ||
| 900 | 920 | .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .none, .sse2 }, |
| 901 | 921 | |
| 902 | 922 | .{ .movapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .none, .sse2 }, |
| ... | ... | @@ -914,6 +934,8 @@ pub const table = [_]Entry{ |
| 914 | 934 | .{ .movupd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x10 }, 0, .none, .sse2 }, |
| 915 | 935 | .{ .movupd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x11 }, 0, .none, .sse2 }, |
| 916 | 936 | |
| 937 | .{ .mulpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x59 }, 0, .none, .sse2 }, | |
| 938 | ||
| 917 | 939 | .{ .mulsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .none, .sse2 }, |
| 918 | 940 | |
| 919 | 941 | .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 }, |
| ... | ... | @@ -947,6 +969,8 @@ pub const table = [_]Entry{ |
| 947 | 969 | |
| 948 | 970 | .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 }, |
| 949 | 971 | |
| 972 | .{ .subpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5c }, 0, .none, .sse2 }, | |
| 973 | ||
| 950 | 974 | .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .none, .sse2 }, |
| 951 | 975 | |
| 952 | 976 | .{ .movsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .none, .sse2 }, |
| ... | ... | @@ -966,10 +990,25 @@ pub const table = [_]Entry{ |
| 966 | 990 | // SSE4.1 |
| 967 | 991 | .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 }, |
| 968 | 992 | |
| 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 | 997 | .{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .none, .sse4_1 }, |
| 971 | 998 | |
| 999 | .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .none, .sse4_1 }, | |
| 1000 | ||
| 972 | 1001 | // 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 | 1012 | .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx }, |
| 974 | 1013 | |
| 975 | 1014 | .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx }, |
| ... | ... | @@ -980,6 +1019,36 @@ pub const table = [_]Entry{ |
| 980 | 1019 | |
| 981 | 1020 | .{ .vcvtss2sd, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx }, |
| 982 | 1021 | |
| 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 | 1052 | .{ .vmovapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .vex_128_wig, .avx }, |
| 984 | 1053 | .{ .vmovapd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x29 }, 0, .vex_128_wig, .avx }, |
| 985 | 1054 | .{ .vmovapd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x28 }, 0, .vex_256_wig, .avx }, |
| ... | ... | @@ -1019,6 +1088,16 @@ pub const table = [_]Entry{ |
| 1019 | 1088 | .{ .vmovups, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x0f, 0x10 }, 0, .vex_256_wig, .avx }, |
| 1020 | 1089 | .{ .vmovups, .mr, &.{ .ymm_m256, .ymm }, &.{ 0x0f, 0x11 }, 0, .vex_256_wig, .avx }, |
| 1021 | 1090 | |
| 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 | 1101 | .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx }, |
| 1023 | 1102 | .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx }, |
| 1024 | 1103 | |
| ... | ... | @@ -1041,6 +1120,16 @@ pub const table = [_]Entry{ |
| 1041 | 1120 | .{ .vpunpckldq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_128_wig, .avx }, |
| 1042 | 1121 | .{ .vpunpcklqdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_128_wig, .avx }, |
| 1043 | 1122 | |
| 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 | 1133 | .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx }, |
| 1045 | 1134 | .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx }, |
| 1046 | 1135 | |
| ... | ... | @@ -1051,6 +1140,16 @@ pub const table = [_]Entry{ |
| 1051 | 1140 | |
| 1052 | 1141 | .{ .vsqrtss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .vex_lig_wig, .avx }, |
| 1053 | 1142 | |
| 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 | 1153 | // F16C |
| 1055 | 1154 | .{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c }, |
| 1056 | 1155 | .{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c }, |