| 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,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 | fn asmRegisterRegisterImmediate( | 1194 | fn 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 | else | 2347 | 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 | else | 2408 | 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); |
| 4533 | 4570 | ||
| 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 | else | 4600 | 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 | } |
| 5802 | 5851 | ||
| 5803 | /// Result is always a register. | ||
| 5804 | fn genBinOp( | 5852 | fn 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 | } | ||
| 5818 | 5864 | ||
| 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 | } |
| 5829 | 5875 | ||
| 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( |
| 5841 | 5888 | ||
| 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 | }; |
| 5858 | 5895 | ||
| 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); |
| 5864 | 5901 | ||
| 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); |
| 5870 | 5907 | ||
| 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()) and | 5915 | 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); |
| 5893 | 5934 | ||
| 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), | ||
| 5964 | 5941 | ||
| 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 | }, | ||
| 6016 | 5945 | ||
| 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); |
| 6024 | 5953 | ||
| 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 | }, |
| 6033 | 5962 | ||
| 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), |
| 6037 | 5966 | ||
| 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), |
| 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, | 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( |
| 6070 | 5998 | ||
| 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 | } | ||
| 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 | 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 | } |
| 9648 | 9763 | ||
| 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 | else | 9866 | 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 | } |
| 9760 | 9872 |
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 | // MMX | 262 | // MMX |
| 263 | movd, | 263 | movd, |
| 264 | // SSE | 264 | // 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 | // SSE2 | 281 | // 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 | // SSE3 | 303 | // SSE3 |
| 303 | movddup, movshdup, movsldup, | 304 | movddup, movshdup, movsldup, |
| 304 | // SSE4.1 | 305 | // SSE4.1 |
| 305 | roundsd, roundss, | 306 | roundpd, roundps, roundsd, roundss, |
| 306 | // AVX | 307 | // 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 | // F16C | 328 | // F16C |
| 321 | vcvtph2ps, vcvtps2ph, | 329 | vcvtph2ps, vcvtps2ph, |
| 322 | // FMA | 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,27 +124,34 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 124 | .xchg, | 124 | .xchg, |
| 125 | .xor, | 125 | .xor, |
| 126 | 126 | ||
| 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, |
| 147 | 153 | ||
| 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, |
| 183 | 195 | ||
| 196 | .roundpd, | ||
| 197 | .roundps, | ||
| 184 | .roundsd, | 198 | .roundsd, |
| 185 | .roundss, | 199 | .roundss, |
| 186 | 200 | ||
| 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, | ||
| 219 | 261 | ||
| 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)), |
| 306 | 348 | ||
| 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-or | 166 | /// Logical exclusive-or |
| 167 | xor, | 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 | addss, | 172 | addss, |
| 171 | /// Bitwise logical and of packed single precision floating-point values | 173 | /// 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 value | 179 | /// 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 values | 183 | /// Divide scalar single-precision floating-point values |
| 180 | divss, | 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 | maxss, | 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 | minss, | 192 | minss, |
| 185 | /// Move aligned packed single-precision floating-point values | 193 | /// 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 values | 197 | /// 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 values | 201 | /// Multiply scalar single-precision floating-point values |
| 192 | mulss, | 202 | mulss, |
| 193 | /// Bitwise logical or of packed single precision floating-point values | 203 | /// 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 word | 207 | /// Insert word |
| 198 | pinsrw, | 208 | pinsrw, |
| 199 | /// Square root of scalar single precision floating-point value | 209 | /// Square root of packed single-precision floating-point values |
| 200 | sqrtps, | 210 | sqrtps, |
| 201 | /// Subtract scalar single-precision floating-point values | 211 | /// Square root of scalar single-precision floating-point value |
| 202 | sqrtss, | 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 | subss, | 216 | subss, |
| 205 | /// Unordered compare scalar single-precision floating-point values | 217 | /// Unordered compare scalar single-precision floating-point values |
| 206 | ucomiss, | 218 | ucomiss, |
| 207 | /// Bitwise logical xor of packed single precision floating-point values | 219 | /// Bitwise logical xor of packed single precision floating-point values |
| 208 | xorps, | 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 | addsd, | 225 | addsd, |
| 212 | /// Bitwise logical and not of packed double precision floating-point values | 226 | /// 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 value | 236 | /// 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 values | 240 | /// Divide scalar double-precision floating-point values |
| 225 | divsd, | 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 | maxsd, | 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 | minsd, | 249 | minsd, |
| 230 | /// Move scalar double-precision floating-point value | 250 | /// 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 values | 254 | /// Multiply scalar double-precision floating-point values |
| 233 | mulsd, | 255 | mulsd, |
| 234 | /// Bitwise logical or of packed double precision floating-point values | 256 | /// 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 value | 286 | /// 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 values | 290 | /// Subtract scalar double-precision floating-point values |
| 267 | subsd, | 291 | subsd, |
| 268 | /// Unordered compare scalar double-precision floating-point values | 292 | /// 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 values | 301 | /// Replicate single floating-point values |
| 278 | movsldup, | 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 | roundsd, | 309 | roundsd, |
| 282 | /// Round scalar single-precision floating-point values | 310 | /// Round scalar single-precision floating-point value |
| 283 | roundss, | 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 | /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value | 321 | /// 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 value | 323 | /// 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 value | 327 | /// 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 values | 353 | /// Move aligned packed double-precision floating-point values |
| 294 | vmovapd, | 354 | vmovapd, |
| 295 | /// Move aligned packed single-precision floating-point values | 355 | /// 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 values | 369 | /// 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 word | 379 | /// Extract word |
| 312 | vpextrw, | 380 | vpextrw, |
| 313 | /// Insert word | 381 | /// 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 data | 407 | /// 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 value | 417 | /// Square root of packed double-precision floating-point value |
| 342 | vsqrtpd, | 418 | vsqrtpd, |
| 343 | /// Square root of packed single-precision floating-point value | 419 | /// 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 value | 423 | /// 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, | ||
| 349 | 433 | ||
| 350 | /// Convert 16-bit floating-point values to single-precision floating-point values | 434 | /// 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 }, |
| 838 | 838 | ||
| 839 | // SSE | 839 | // 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 }, |
| 841 | 843 | ||
| 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 }, |
| 850 | 852 | ||
| 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 }, |
| 852 | 856 | ||
| 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 }, |
| 854 | 860 | ||
| 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 }, |
| 856 | 864 | ||
| 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 }, |
| 865 | 873 | ||
| 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 }, |
| 867 | 877 | ||
| 868 | .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse }, | 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 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, | 882 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, |
| 871 | 883 | ||
| 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 }, |
| 879 | 891 | ||
| 880 | // SSE2 | 892 | // 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 }, |
| 882 | 896 | ||
| 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{ |
| 893 | 907 | ||
| 894 | .{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .none, .sse2 }, | 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 | .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 }, | 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 | .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .none, .sse2 }, | 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 | .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .none, .sse2 }, | 920 | .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .none, .sse2 }, |
| 901 | 921 | ||
| 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 }, |
| 916 | 936 | ||
| 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 }, |
| 918 | 940 | ||
| 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{ |
| 947 | 969 | ||
| 948 | .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 }, | 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 | .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .none, .sse2 }, | 974 | .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .none, .sse2 }, |
| 951 | 975 | ||
| 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.1 | 990 | // 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 }, |
| 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 | .{ .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 }, |
| 971 | 998 | ||
| 999 | .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .none, .sse4_1 }, | ||
| 1000 | |||
| 972 | // AVX | 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 | .{ .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 }, |
| 974 | 1013 | ||
| 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{ |
| 980 | 1019 | ||
| 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 }, |
| 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 | .{ .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 }, |
| 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 | .{ .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 }, |
| 1024 | 1103 | ||
| ... | @@ -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 }, |
| 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 | .{ .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 }, |
| 1046 | 1135 | ||
| ... | @@ -1051,6 +1140,16 @@ pub const table = [_]Entry{ | ... | @@ -1051,6 +1140,16 @@ pub const table = [_]Entry{ |
| 1051 | 1140 | ||
| 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 }, |
| 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 | // F16C | 1153 | // 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 }, |