| ... | ... | @@ -1210,6 +1210,28 @@ fn asmRegisterMemory(self: *Self, tag: Mir.Inst.Tag, reg: Register, m: Memory) ! |
| 1210 | 1210 | }); |
| 1211 | 1211 | } |
| 1212 | 1212 | |
| 1213 | fn 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 | |
| 1213 | 1235 | fn asmMemoryRegister(self: *Self, tag: Mir.Inst.Tag, m: Memory, reg: Register) !void { |
| 1214 | 1236 | _ = try self.addInst(.{ |
| 1215 | 1237 | .tag = tag, |
| ... | ... | @@ -1951,7 +1973,7 @@ fn allocRegOrMemAdvanced(self: *Self, elem_ty: Type, inst: ?Air.Inst.Index, reg_ |
| 1951 | 1973 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 1952 | 1974 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 1953 | 1975 | 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| { |
| 1955 | 1977 | return MCValue{ .register = registerAlias(reg, abi_size) }; |
| 1956 | 1978 | } |
| 1957 | 1979 | } |
| ... | ... | @@ -1961,14 +1983,9 @@ fn allocRegOrMemAdvanced(self: *Self, elem_ty: Type, inst: ?Air.Inst.Index, reg_ |
| 1961 | 1983 | return .{ .load_frame = .{ .index = frame_index } }; |
| 1962 | 1984 | } |
| 1963 | 1985 | |
| 1964 | | fn regClassForType(self: *Self, ty: Type) !RegisterManager.RegisterBitSet { |
| 1986 | fn regClassForType(ty: Type) RegisterManager.RegisterBitSet { |
| 1965 | 1987 | 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, |
| 1972 | 1989 | else => gp, |
| 1973 | 1990 | }; |
| 1974 | 1991 | } |
| ... | ... | @@ -2111,7 +2128,7 @@ pub fn spillRegisters(self: *Self, registers: []const Register) !void { |
| 2111 | 2128 | /// allocated. A second call to `copyToTmpRegister` may return the same register. |
| 2112 | 2129 | /// This can have a side effect of spilling instructions to the stack to free up a register. |
| 2113 | 2130 | fn 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)); |
| 2115 | 2132 | try self.genSetReg(reg, ty, mcv); |
| 2116 | 2133 | return reg; |
| 2117 | 2134 | } |
| ... | ... | @@ -2126,7 +2143,7 @@ fn copyToRegisterWithInstTracking( |
| 2126 | 2143 | ty: Type, |
| 2127 | 2144 | mcv: MCValue, |
| 2128 | 2145 | ) !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)); |
| 2130 | 2147 | try self.genSetReg(reg, ty, mcv); |
| 2131 | 2148 | return MCValue{ .register = reg }; |
| 2132 | 2149 | } |
| ... | ... | @@ -2159,8 +2176,7 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2159 | 2176 | if (dst_ty.floatBits(self.target.*) != 32 or src_ty.floatBits(self.target.*) != 64 or |
| 2160 | 2177 | !Target.x86.featureSetHas(self.target.cpu.features, .sse2)) |
| 2161 | 2178 | 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.?), |
| 2164 | 2180 | }); |
| 2165 | 2181 | |
| 2166 | 2182 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | ... | @@ -2182,8 +2198,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2182 | 2198 | if (dst_ty.floatBits(self.target.*) != 64 or src_ty.floatBits(self.target.*) != 32 or |
| 2183 | 2199 | !Target.x86.featureSetHas(self.target.cpu.features, .sse2)) |
| 2184 | 2200 | 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.?), |
| 2187 | 2202 | }); |
| 2188 | 2203 | |
| 2189 | 2204 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | ... | @@ -4436,8 +4451,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4436 | 4451 | const ptr_ty = self.air.typeOf(ty_op.operand); |
| 4437 | 4452 | const elem_size = elem_ty.abiSize(self.target.*); |
| 4438 | 4453 | |
| 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); |
| 4441 | 4456 | |
| 4442 | 4457 | const ptr_mcv = try self.resolveInst(ty_op.operand); |
| 4443 | 4458 | const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and |
| ... | ... | @@ -5257,8 +5272,7 @@ fn genMulDivBinOp( |
| 5257 | 5272 | .mul, .mulwrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2, |
| 5258 | 5273 | .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_abi_size != src_abi_size, |
| 5259 | 5274 | } 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.?), |
| 5262 | 5276 | }); |
| 5263 | 5277 | const ty = if (dst_abi_size <= 8) dst_ty else src_ty; |
| 5264 | 5278 | const abi_size = if (dst_abi_size <= 8) dst_abi_size else src_abi_size; |
| ... | ... | @@ -5558,7 +5572,9 @@ fn genBinOp( |
| 5558 | 5572 | }, lhs_ty, dst_mcv, src_mcv), |
| 5559 | 5573 | |
| 5560 | 5574 | .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 | }), |
| 5562 | 5578 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 5563 | 5579 | 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse)) |
| 5564 | 5580 | .mulss |
| ... | ... | @@ -5761,9 +5777,13 @@ fn genBinOp( |
| 5761 | 5777 | .max => .maxsd, |
| 5762 | 5778 | else => unreachable, |
| 5763 | 5779 | }, |
| 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 | }), |
| 5765 | 5783 | }, 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 | }), |
| 5767 | 5787 | }, |
| 5768 | 5788 | |
| 5769 | 5789 | else => unreachable, |
| ... | ... | @@ -5802,8 +5822,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5802 | 5822 | .Float => { |
| 5803 | 5823 | if (!Target.x86.featureSetHas(self.target.cpu.features, .sse)) |
| 5804 | 5824 | 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.?), |
| 5807 | 5826 | }); |
| 5808 | 5827 | return self.asmRegisterRegister(mir_tag, dst_reg.to128(), src_reg.to128()); |
| 5809 | 5828 | }, |
| ... | ... | @@ -7588,10 +7607,11 @@ fn movMirTag(self: *Self, ty: Type) !Mir.Inst.Tag { |
| 7588 | 7607 | return switch (ty.zigTypeTag()) { |
| 7589 | 7608 | else => .mov, |
| 7590 | 7609 | .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 {}", .{ |
| 7595 | 7615 | ty.fmt(self.bin_file.options.module.?), |
| 7596 | 7616 | }), |
| 7597 | 7617 | }, |
| ... | ... | @@ -7700,8 +7720,17 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7700 | 7720 | }, |
| 7701 | 7721 | .register => |src_reg| if (dst_reg.id() != src_reg.id()) try self.asmRegisterRegister( |
| 7702 | 7722 | 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 | } |
| 7704 | 7727 | 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 | ), |
| 7705 | 7734 | 4 => .movd, |
| 7706 | 7735 | 8 => .movq, |
| 7707 | 7736 | else => return self.fail( |
| ... | ... | @@ -7712,18 +7741,12 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7712 | 7741 | registerAlias(dst_reg, abi_size), |
| 7713 | 7742 | registerAlias(src_reg, abi_size), |
| 7714 | 7743 | ), |
| 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) { |
| 7727 | 7750 | .register_offset, .indirect => |reg_off| .{ |
| 7728 | 7751 | .base = .{ .reg = reg_off.reg }, |
| 7729 | 7752 | .disp = reg_off.off, |
| ... | ... | @@ -7733,20 +7756,51 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7733 | 7756 | .disp = frame_addr.off, |
| 7734 | 7757 | }, |
| 7735 | 7758 | 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 | }, |
| 7738 | 7782 | .memory, .load_direct, .load_got, .load_tlv => { |
| 7739 | 7783 | 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()) { |
| 7750 | 7804 | const atom_index = try self.owner.getSymbolIndex(self); |
| 7751 | 7805 | _ = try self.addInst(.{ |
| 7752 | 7806 | .tag = .mov_linker, |
| ... | ... | @@ -7767,11 +7821,22 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7767 | 7821 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7768 | 7822 | defer self.register_manager.unlockReg(addr_lock); |
| 7769 | 7823 | |
| 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 | ); |
| 7775 | 7840 | }, |
| 7776 | 7841 | .lea_direct, .lea_got => |sym_index| { |
| 7777 | 7842 | 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 |
| 7864 | 7929 | }, |
| 7865 | 7930 | }, |
| 7866 | 7931 | .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 | }, |
| 7872 | 7951 | .register_overflow => |ro| { |
| 7873 | 7952 | try self.genSetMem( |
| 7874 | 7953 | base, |
| ... | ... | @@ -8071,8 +8150,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 8071 | 8150 | const src_ty = self.air.typeOf(ty_op.operand); |
| 8072 | 8151 | |
| 8073 | 8152 | 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); |
| 8076 | 8155 | const operand = try self.resolveInst(ty_op.operand); |
| 8077 | 8156 | if (dst_rc.supersetOf(src_rc) and self.reuseOperand(inst, ty_op.operand, 0, operand)) |
| 8078 | 8157 | break :result operand; |
| ... | ... | @@ -8127,8 +8206,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 8127 | 8206 | .unsigned => src_bits + 1, |
| 8128 | 8207 | }, 32), 8) catch unreachable; |
| 8129 | 8208 | 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.?), |
| 8132 | 8210 | }); |
| 8133 | 8211 | |
| 8134 | 8212 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | ... | @@ -8141,7 +8219,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 8141 | 8219 | |
| 8142 | 8220 | if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg); |
| 8143 | 8221 | |
| 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)); |
| 8145 | 8223 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 8146 | 8224 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 8147 | 8225 | defer self.register_manager.unlockReg(dst_lock); |
| ... | ... | @@ -8151,19 +8229,16 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 8151 | 8229 | .cvtsi2ss |
| 8152 | 8230 | else |
| 8153 | 8231 | 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.?), |
| 8156 | 8233 | }), |
| 8157 | 8234 | 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2)) |
| 8158 | 8235 | .cvtsi2sd |
| 8159 | 8236 | else |
| 8160 | 8237 | 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.?), |
| 8163 | 8239 | }), |
| 8164 | 8240 | 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.?), |
| 8167 | 8242 | }), |
| 8168 | 8243 | }, dst_reg.to128(), registerAlias(src_reg, src_size)); |
| 8169 | 8244 | |