authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-03 04:21:40-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-03 04:25:14-04:00
loga19faa2481e84e065a8762cb7c7cbf35426929fd
treebac1c8e73a43ab9a855107776ff3223528426b84
parent6893f90887836584f9377793cca7235d8947a326

x86_64: implement movement of more types

* f16 * f128 * vector

6 files changed, 198 insertions(+), 80 deletions(-)

src/arch/x86_64/CodeGen.zig+148-73
......@@ -1210,6 +1210,28 @@ fn asmRegisterMemory(self: *Self, tag: Mir.Inst.Tag, reg: Register, m: Memory) !
12101210 });
12111211}
12121212
1213fn asmRegisterMemoryImmediate(
1214 self: *Self,
1215 tag: Mir.Inst.Tag,
1216 reg: Register,
1217 m: Memory,
1218 imm: Immediate,
1219) !void {
1220 _ = try self.addInst(.{
1221 .tag = tag,
1222 .ops = switch (m) {
1223 .sib => .rmi_sib,
1224 .rip => .rmi_rip,
1225 else => unreachable,
1226 },
1227 .data = .{ .rix = .{ .r = reg, .i = @intCast(u8, imm.unsigned), .payload = switch (m) {
1228 .sib => try self.addExtra(Mir.MemorySib.encode(m)),
1229 .rip => try self.addExtra(Mir.MemoryRip.encode(m)),
1230 else => unreachable,
1231 } } },
1232 });
1233}
1234
12131235fn asmMemoryRegister(self: *Self, tag: Mir.Inst.Tag, m: Memory, reg: Register) !void {
12141236 _ = try self.addInst(.{
12151237 .tag = tag,
......@@ -1951,7 +1973,7 @@ fn allocRegOrMemAdvanced(self: *Self, elem_ty: Type, inst: ?Air.Inst.Index, reg_
19511973 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
19521974 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
19531975 if (abi_size <= ptr_bytes) {
1954 if (self.register_manager.tryAllocReg(inst, try self.regClassForType(elem_ty))) |reg| {
1976 if (self.register_manager.tryAllocReg(inst, regClassForType(elem_ty))) |reg| {
19551977 return MCValue{ .register = registerAlias(reg, abi_size) };
19561978 }
19571979 }
......@@ -1961,14 +1983,9 @@ fn allocRegOrMemAdvanced(self: *Self, elem_ty: Type, inst: ?Air.Inst.Index, reg_
19611983 return .{ .load_frame = .{ .index = frame_index } };
19621984}
19631985
1964fn regClassForType(self: *Self, ty: Type) !RegisterManager.RegisterBitSet {
1986fn regClassForType(ty: Type) RegisterManager.RegisterBitSet {
19651987 return switch (ty.zigTypeTag()) {
1966 .Vector => self.fail("TODO regClassForType for {}", .{ty.fmt(self.bin_file.options.module.?)}),
1967 .Float => switch (ty.floatBits(self.target.*)) {
1968 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse)) sse else gp,
1969 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2)) sse else gp,
1970 else => gp,
1971 },
1988 .Float, .Vector => sse,
19721989 else => gp,
19731990 };
19741991}
......@@ -2111,7 +2128,7 @@ pub fn spillRegisters(self: *Self, registers: []const Register) !void {
21112128/// allocated. A second call to `copyToTmpRegister` may return the same register.
21122129/// This can have a side effect of spilling instructions to the stack to free up a register.
21132130fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
2114 const reg = try self.register_manager.allocReg(null, try self.regClassForType(ty));
2131 const reg = try self.register_manager.allocReg(null, regClassForType(ty));
21152132 try self.genSetReg(reg, ty, mcv);
21162133 return reg;
21172134}
......@@ -2126,7 +2143,7 @@ fn copyToRegisterWithInstTracking(
21262143 ty: Type,
21272144 mcv: MCValue,
21282145) !MCValue {
2129 const reg: Register = try self.register_manager.allocReg(reg_owner, try self.regClassForType(ty));
2146 const reg: Register = try self.register_manager.allocReg(reg_owner, regClassForType(ty));
21302147 try self.genSetReg(reg, ty, mcv);
21312148 return MCValue{ .register = reg };
21322149}
......@@ -2159,8 +2176,7 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
21592176 if (dst_ty.floatBits(self.target.*) != 32 or src_ty.floatBits(self.target.*) != 64 or
21602177 !Target.x86.featureSetHas(self.target.cpu.features, .sse2))
21612178 return self.fail("TODO implement airFptrunc from {} to {}", .{
2162 src_ty.fmt(self.bin_file.options.module.?),
2163 dst_ty.fmt(self.bin_file.options.module.?),
2179 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
21642180 });
21652181
21662182 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -2182,8 +2198,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
21822198 if (dst_ty.floatBits(self.target.*) != 64 or src_ty.floatBits(self.target.*) != 32 or
21832199 !Target.x86.featureSetHas(self.target.cpu.features, .sse2))
21842200 return self.fail("TODO implement airFpext from {} to {}", .{
2185 src_ty.fmt(self.bin_file.options.module.?),
2186 dst_ty.fmt(self.bin_file.options.module.?),
2201 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
21872202 });
21882203
21892204 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -4436,8 +4451,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
44364451 const ptr_ty = self.air.typeOf(ty_op.operand);
44374452 const elem_size = elem_ty.abiSize(self.target.*);
44384453
4439 const elem_rc = try self.regClassForType(elem_ty);
4440 const ptr_rc = try self.regClassForType(ptr_ty);
4454 const elem_rc = regClassForType(elem_ty);
4455 const ptr_rc = regClassForType(ptr_ty);
44414456
44424457 const ptr_mcv = try self.resolveInst(ty_op.operand);
44434458 const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and
......@@ -5257,8 +5272,7 @@ fn genMulDivBinOp(
52575272 .mul, .mulwrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,
52585273 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_abi_size != src_abi_size,
52595274 } or src_abi_size > 8) return self.fail("TODO implement genMulDivBinOp from {} to {}", .{
5260 src_ty.fmt(self.bin_file.options.module.?),
5261 dst_ty.fmt(self.bin_file.options.module.?),
5275 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
52625276 });
52635277 const ty = if (dst_abi_size <= 8) dst_ty else src_ty;
52645278 const abi_size = if (dst_abi_size <= 8) dst_abi_size else src_abi_size;
......@@ -5558,7 +5572,9 @@ fn genBinOp(
55585572 }, lhs_ty, dst_mcv, src_mcv),
55595573
55605574 .mul => try self.genBinOpMir(switch (lhs_ty.zigTypeTag()) {
5561 else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }),
5575 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5576 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5577 }),
55625578 .Float => switch (lhs_ty.floatBits(self.target.*)) {
55635579 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse))
55645580 .mulss
......@@ -5761,9 +5777,13 @@ fn genBinOp(
57615777 .max => .maxsd,
57625778 else => unreachable,
57635779 },
5764 else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }),
5780 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5781 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5782 }),
57655783 }, lhs_ty, dst_mcv, src_mcv),
5766 else => return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?) }),
5784 else => return self.fail("TODO implement genBinOp for {s} {}", .{
5785 @tagName(tag), lhs_ty.fmt(self.bin_file.options.module.?),
5786 }),
57675787 },
57685788
57695789 else => unreachable,
......@@ -5802,8 +5822,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
58025822 .Float => {
58035823 if (!Target.x86.featureSetHas(self.target.cpu.features, .sse))
58045824 return self.fail("TODO genBinOpMir for {s} {} without sse", .{
5805 @tagName(mir_tag),
5806 ty.fmt(self.bin_file.options.module.?),
5825 @tagName(mir_tag), ty.fmt(self.bin_file.options.module.?),
58075826 });
58085827 return self.asmRegisterRegister(mir_tag, dst_reg.to128(), src_reg.to128());
58095828 },
......@@ -7588,10 +7607,11 @@ fn movMirTag(self: *Self, ty: Type) !Mir.Inst.Tag {
75887607 return switch (ty.zigTypeTag()) {
75897608 else => .mov,
75907609 .Float => switch (ty.floatBits(self.target.*)) {
7591 16 => .mov,
7592 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse)) .movss else .mov,
7593 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2)) .movsd else .mov,
7594 else => return self.fail("TODO movMirTag for {}", .{
7610 16 => unreachable, // needs special handling
7611 32 => .movss,
7612 64 => .movsd,
7613 128 => .movaps,
7614 else => return self.fail("TODO movMirTag from {}", .{
75957615 ty.fmt(self.bin_file.options.module.?),
75967616 }),
75977617 },
......@@ -7700,8 +7720,17 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
77007720 },
77017721 .register => |src_reg| if (dst_reg.id() != src_reg.id()) try self.asmRegisterRegister(
77027722 if ((dst_reg.class() == .floating_point) == (src_reg.class() == .floating_point))
7703 try self.movMirTag(ty)
7723 switch (ty.zigTypeTag()) {
7724 else => .mov,
7725 .Float, .Vector => .movaps,
7726 }
77047727 else switch (abi_size) {
7728 2 => return try self.asmRegisterRegisterImmediate(
7729 if (dst_reg.class() == .floating_point) .pinsrw else .pextrw,
7730 registerAlias(dst_reg, abi_size),
7731 registerAlias(src_reg, abi_size),
7732 Immediate.u(0),
7733 ),
77057734 4 => .movd,
77067735 8 => .movq,
77077736 else => return self.fail(
......@@ -7712,18 +7741,12 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
77127741 registerAlias(dst_reg, abi_size),
77137742 registerAlias(src_reg, abi_size),
77147743 ),
7715 .register_offset, .indirect, .load_frame, .lea_frame => try self.asmRegisterMemory(
7716 switch (src_mcv) {
7717 .register_offset => |reg_off| switch (reg_off.off) {
7718 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }),
7719 else => .lea,
7720 },
7721 .indirect, .load_frame => try self.movMirTag(ty),
7722 .lea_frame => .lea,
7723 else => unreachable,
7724 },
7725 registerAlias(dst_reg, abi_size),
7726 Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) {
7744 .register_offset,
7745 .indirect,
7746 .load_frame,
7747 .lea_frame,
7748 => {
7749 const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) {
77277750 .register_offset, .indirect => |reg_off| .{
77287751 .base = .{ .reg = reg_off.reg },
77297752 .disp = reg_off.off,
......@@ -7733,20 +7756,51 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
77337756 .disp = frame_addr.off,
77347757 },
77357758 else => unreachable,
7736 }),
7737 ),
7759 });
7760 if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16)
7761 try self.asmRegisterMemoryImmediate(
7762 .pinsrw,
7763 registerAlias(dst_reg, abi_size),
7764 src_mem,
7765 Immediate.u(0),
7766 )
7767 else
7768 try self.asmRegisterMemory(
7769 switch (src_mcv) {
7770 .register_offset => |reg_off| switch (reg_off.off) {
7771 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }),
7772 else => .lea,
7773 },
7774 .indirect, .load_frame => try self.movMirTag(ty),
7775 .lea_frame => .lea,
7776 else => unreachable,
7777 },
7778 registerAlias(dst_reg, abi_size),
7779 src_mem,
7780 );
7781 },
77387782 .memory, .load_direct, .load_got, .load_tlv => {
77397783 switch (src_mcv) {
7740 .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr|
7741 return self.asmRegisterMemory(
7742 try self.movMirTag(ty),
7743 registerAlias(dst_reg, abi_size),
7744 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{
7745 .base = .{ .reg = .ds },
7746 .disp = small_addr,
7747 }),
7748 ),
7749 .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) {
7784 .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr| {
7785 const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{
7786 .base = .{ .reg = .ds },
7787 .disp = small_addr,
7788 });
7789 return if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16)
7790 self.asmRegisterMemoryImmediate(
7791 .pinsrw,
7792 registerAlias(dst_reg, abi_size),
7793 src_mem,
7794 Immediate.u(0),
7795 )
7796 else
7797 self.asmRegisterMemory(
7798 try self.movMirTag(ty),
7799 registerAlias(dst_reg, abi_size),
7800 src_mem,
7801 );
7802 },
7803 .load_direct => |sym_index| if (!ty.isRuntimeFloat()) {
77507804 const atom_index = try self.owner.getSymbolIndex(self);
77517805 _ = try self.addInst(.{
77527806 .tag = .mov_linker,
......@@ -7767,11 +7821,22 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
77677821 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
77687822 defer self.register_manager.unlockReg(addr_lock);
77697823
7770 try self.asmRegisterMemory(
7771 try self.movMirTag(ty),
7772 registerAlias(dst_reg, abi_size),
7773 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),
7774 );
7824 const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{
7825 .base = .{ .reg = addr_reg },
7826 });
7827 if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16)
7828 try self.asmRegisterMemoryImmediate(
7829 .pinsrw,
7830 registerAlias(dst_reg, abi_size),
7831 src_mem,
7832 Immediate.u(0),
7833 )
7834 else
7835 try self.asmRegisterMemory(
7836 try self.movMirTag(ty),
7837 registerAlias(dst_reg, abi_size),
7838 src_mem,
7839 );
77757840 },
77767841 .lea_direct, .lea_got => |sym_index| {
77777842 const atom_index = try self.owner.getSymbolIndex(self);
......@@ -7864,11 +7929,25 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
78647929 },
78657930 },
78667931 .eflags => |cc| try self.asmSetccMemory(Memory.sib(.byte, .{ .base = base, .disp = disp }), cc),
7867 .register => |reg| try self.asmMemoryRegister(
7868 try self.movMirTag(ty),
7869 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }),
7870 registerAlias(reg, abi_size),
7871 ),
7932 .register => |src_reg| {
7933 const dst_mem = Memory.sib(
7934 Memory.PtrSize.fromSize(abi_size),
7935 .{ .base = base, .disp = disp },
7936 );
7937 if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16)
7938 try self.asmMemoryRegisterImmediate(
7939 .pextrw,
7940 dst_mem,
7941 registerAlias(src_reg, abi_size),
7942 Immediate.u(0),
7943 )
7944 else
7945 try self.asmMemoryRegister(
7946 try self.movMirTag(ty),
7947 dst_mem,
7948 registerAlias(src_reg, abi_size),
7949 );
7950 },
78727951 .register_overflow => |ro| {
78737952 try self.genSetMem(
78747953 base,
......@@ -8071,8 +8150,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
80718150 const src_ty = self.air.typeOf(ty_op.operand);
80728151
80738152 const result = result: {
8074 const dst_rc = try self.regClassForType(dst_ty);
8075 const src_rc = try self.regClassForType(src_ty);
8153 const dst_rc = regClassForType(dst_ty);
8154 const src_rc = regClassForType(src_ty);
80768155 const operand = try self.resolveInst(ty_op.operand);
80778156 if (dst_rc.supersetOf(src_rc) and self.reuseOperand(inst, ty_op.operand, 0, operand))
80788157 break :result operand;
......@@ -8127,8 +8206,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
81278206 .unsigned => src_bits + 1,
81288207 }, 32), 8) catch unreachable;
81298208 if (src_size > 8) return self.fail("TODO implement airIntToFloat from {} to {}", .{
8130 src_ty.fmt(self.bin_file.options.module.?),
8131 dst_ty.fmt(self.bin_file.options.module.?),
8209 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
81328210 });
81338211
81348212 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -8141,7 +8219,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
81418219
81428220 if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg);
81438221
8144 const dst_reg = try self.register_manager.allocReg(inst, try self.regClassForType(dst_ty));
8222 const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty));
81458223 const dst_mcv = MCValue{ .register = dst_reg };
81468224 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
81478225 defer self.register_manager.unlockReg(dst_lock);
......@@ -8151,19 +8229,16 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
81518229 .cvtsi2ss
81528230 else
81538231 return self.fail("TODO implement airIntToFloat from {} to {} without sse", .{
8154 src_ty.fmt(self.bin_file.options.module.?),
8155 dst_ty.fmt(self.bin_file.options.module.?),
8232 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
81568233 }),
81578234 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2))
81588235 .cvtsi2sd
81598236 else
81608237 return self.fail("TODO implement airIntToFloat from {} to {} without sse2", .{
8161 src_ty.fmt(self.bin_file.options.module.?),
8162 dst_ty.fmt(self.bin_file.options.module.?),
8238 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
81638239 }),
81648240 else => return self.fail("TODO implement airIntToFloat from {} to {}", .{
8165 src_ty.fmt(self.bin_file.options.module.?),
8166 dst_ty.fmt(self.bin_file.options.module.?),
8241 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
81678242 }),
81688243 }, dst_reg.to128(), registerAlias(src_reg, src_size));
81698244
src/arch/x86_64/Encoding.zig+5-1
......@@ -274,9 +274,11 @@ pub const Mnemonic = enum {
274274 cvtsi2ss,
275275 divss,
276276 maxss, minss,
277 movss,
277 movaps, movss, movups,
278278 mulss,
279279 orps,
280 pextrw,
281 pinsrw,
280282 sqrtps,
281283 sqrtss,
282284 subss,
......@@ -290,7 +292,9 @@ pub const Mnemonic = enum {
290292 cvtsd2ss, cvtsi2sd, cvtss2sd,
291293 divsd,
292294 maxsd, minsd,
295 movapd,
293296 movq, //movd, movsd,
297 movupd,
294298 mulsd,
295299 orpd,
296300 sqrtpd,
src/arch/x86_64/Lower.zig+13
......@@ -101,9 +101,13 @@ pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction {
101101 .divss,
102102 .maxss,
103103 .minss,
104 .movaps,
104105 .movss,
106 .movups,
105107 .mulss,
106108 .orps,
109 .pextrw,
110 .pinsrw,
107111 .roundss,
108112 .sqrtps,
109113 .sqrtss,
......@@ -198,6 +202,8 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
198202 .mi_rip_u,
199203 .lock_mi_sib_u,
200204 .lock_mi_rip_u,
205 .rmi_sib,
206 .rmi_rip,
201207 .mri_sib,
202208 .mri_rip,
203209 => Immediate.u(i),
......@@ -212,6 +218,7 @@ fn mem(lower: Lower, ops: Mir.Inst.Ops, payload: u32) Memory {
212218 return lower.mir.resolveFrameLoc(switch (ops) {
213219 .rm_sib,
214220 .rm_sib_cc,
221 .rmi_sib,
215222 .m_sib,
216223 .m_sib_cc,
217224 .mi_sib_u,
......@@ -227,6 +234,7 @@ fn mem(lower: Lower, ops: Mir.Inst.Ops, payload: u32) Memory {
227234
228235 .rm_rip,
229236 .rm_rip_cc,
237 .rmi_rip,
230238 .m_rip,
231239 .m_rip_cc,
232240 .mi_rip_u,
......@@ -321,6 +329,11 @@ fn mirGeneric(lower: *Lower, inst: Mir.Inst) Error!void {
321329 .{ .reg = inst.data.rx.r },
322330 .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) },
323331 },
332 .rmi_sib, .rmi_rip => &.{
333 .{ .reg = inst.data.rix.r },
334 .{ .mem = lower.mem(inst.ops, inst.data.rix.payload) },
335 .{ .imm = lower.imm(inst.ops, inst.data.rix.i) },
336 },
324337 .mr_sib, .lock_mr_sib, .mr_rip, .lock_mr_rip => &.{
325338 .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) },
326339 .{ .reg = inst.data.rx.r },
src/arch/x86_64/Mir.zig+14
......@@ -182,12 +182,20 @@ pub const Inst = struct {
182182 maxss,
183183 /// Return minimum single-precision floating-point value
184184 minss,
185 /// Move aligned packed single-precision floating-point values
186 movaps,
185187 /// Move scalar single-precision floating-point value
186188 movss,
189 /// Move unaligned packed single-precision floating-point values
190 movups,
187191 /// Multiply scalar single-precision floating-point values
188192 mulss,
189193 /// Bitwise logical or of packed single precision floating-point values
190194 orps,
195 /// Extract word
196 pextrw,
197 /// Insert word
198 pinsrw,
191199 /// Round scalar single-precision floating-point values
192200 roundss,
193201 /// Square root of scalar single precision floating-point value
......@@ -346,6 +354,12 @@ pub const Inst = struct {
346354 /// Register, memory (RIP) operands with condition code (CC).
347355 /// Uses `rx_cc` payload.
348356 rm_rip_cc,
357 /// Register, memory (SIB), immediate (byte) operands.
358 /// Uses `rix` payload with extra data of type `MemorySib`.
359 rmi_sib,
360 /// Register, memory (RIP), immediate (byte) operands.
361 /// Uses `rix` payload with extra data of type `MemoryRip`.
362 rmi_rip,
349363 /// Single memory (SIB) operand.
350364 /// Uses `payload` with extra data of type `MemorySib`.
351365 m_sib,
src/arch/x86_64/encodings.zig+18
......@@ -847,9 +847,15 @@ pub const table = [_]Entry{
847847
848848 .{ .minss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .sse },
849849
850 .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .sse },
851 .{ .movaps, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x29 }, 0, .sse },
852
850853 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .sse },
851854 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .sse },
852855
856 .{ .movups, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x10 }, 0, .sse },
857 .{ .movups, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x11 }, 0, .sse },
858
853859 .{ .mulss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .sse },
854860
855861 .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .sse },
......@@ -885,6 +891,9 @@ pub const table = [_]Entry{
885891
886892 .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .sse2 },
887893
894 .{ .movapd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x28 }, 0, .sse2 },
895 .{ .movapd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x29 }, 0, .sse2 },
896
888897 .{ .movd, .rm, &.{ .xmm, .rm32 }, &.{ 0x66, 0x0f, 0x6e }, 0, .sse2 },
889898 .{ .movd, .mr, &.{ .rm32, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .sse2 },
890899
......@@ -894,10 +903,17 @@ pub const table = [_]Entry{
894903 .{ .movq, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0x7e }, 0, .sse2 },
895904 .{ .movq, .mr, &.{ .xmm_m64, .xmm }, &.{ 0x66, 0x0f, 0xd6 }, 0, .sse2 },
896905
906 .{ .movupd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x10 }, 0, .sse2 },
907 .{ .movupd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x11 }, 0, .sse2 },
908
897909 .{ .mulsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .sse2 },
898910
899911 .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .sse2 },
900912
913 .{ .pextrw, .mri, &.{ .r16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0xc5 }, 0, .sse2 },
914
915 .{ .pinsrw, .rmi, &.{ .xmm, .rm16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .sse2 },
916
901917 .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .sse2 },
902918 .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .sse2 },
903919
......@@ -911,6 +927,8 @@ pub const table = [_]Entry{
911927 .{ .xorpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .sse2 },
912928
913929 // SSE4.1
930 .{ .pextrw, .mri, &.{ .rm16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .sse4_1 },
931
914932 .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 },
915933 .{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 },
916934};
test/behavior/vector.zig-6
......@@ -133,7 +133,6 @@ test "vector bit operators" {
133133}
134134
135135test "implicit cast vector to array" {
136 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
137136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
138137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
139138 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -151,7 +150,6 @@ test "implicit cast vector to array" {
151150}
152151
153152test "array to vector" {
154 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
155153 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
156154 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
157155 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -321,7 +319,6 @@ test "load vector elements via comptime index" {
321319 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
322320 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
323321 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
324 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
325322
326323 const S = struct {
327324 fn doTheTest() !void {
......@@ -343,7 +340,6 @@ test "store vector elements via comptime index" {
343340 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
344341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
345342 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
346 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
347343
348344 const S = struct {
349345 fn doTheTest() !void {
......@@ -371,7 +367,6 @@ test "load vector elements via runtime index" {
371367 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
372368 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
373369 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
374 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
375370
376371 const S = struct {
377372 fn doTheTest() !void {
......@@ -393,7 +388,6 @@ test "store vector elements via runtime index" {
393388 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
394389 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
395390 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
396 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
397391
398392 const S = struct {
399393 fn doTheTest() !void {